diff --git a/Directory.Build.props b/Directory.Build.props
index 4107aab1da083..3e494e19c3d9e 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -65,7 +65,7 @@
- src/tasks/AotCompilerTask/MonoAOTCompiler.props
- src/tasks/AppleAppBuilder/Xcode.cs
- src/tasks/MobileBuildTasks/Apple/AppleProject.cs
- - dotnet/installer repo > src/redist/targets/GeneratePKG.targets
+ - https://github.com/dotnet/sdk repo > src/Installer/redist-installer/targets/GeneratePKG.targets
-->
21
12.2
diff --git a/README.md b/README.md
index 1d3328b81b2d6..5f42a80256c42 100644
--- a/README.md
+++ b/README.md
@@ -21,11 +21,11 @@ all supported platforms, as well as the sources to .NET runtime and libraries.
Official Starting Page:
-* [How to use .NET](https://docs.microsoft.com/dotnet/core/get-started) (with VS, VS Code, command-line CLI)
+* [How to use .NET](https://learn.microsoft.com/dotnet/core/get-started) (with VS, VS Code, command-line CLI)
* [Install official releases](https://dotnet.microsoft.com/download)
* [Install daily builds](docs/project/dogfooding.md)
- * [Documentation](https://docs.microsoft.com/dotnet/core) (Get Started, Tutorials, Porting from .NET Framework, API reference, ...)
- * [Deploying apps](https://docs.microsoft.com/dotnet/core/deploying)
+ * [Documentation](https://learn.microsoft.com/dotnet/core) (Get Started, Tutorials, Porting from .NET Framework, API reference, ...)
+ * [Deploying apps](https://learn.microsoft.com/dotnet/core/deploying)
* [Supported OS versions](https://github.com/dotnet/core/blob/main/os-lifecycle-policy.md)
* [Roadmap](https://github.com/dotnet/core/blob/main/roadmap.md)
* [Releases](https://github.com/dotnet/core/tree/main/release-notes)
@@ -53,7 +53,7 @@ For other issues, please file them to their appropriate sibling repos. We have l
## Useful Links
* [.NET source index](https://source.dot.net) / [.NET Framework source index](https://referencesource.microsoft.com)
-* [API Reference docs](https://docs.microsoft.com/dotnet/api)
+* [API Reference docs](https://learn.microsoft.com/dotnet/api)
* [.NET API Catalog](https://apisof.net) (incl. APIs from daily builds and API usage info)
* [API docs writing guidelines](https://github.com/dotnet/dotnet-api-docs/wiki) - useful when writing /// comments
* [.NET Discord Server](https://aka.ms/dotnet-discord) - a place to discuss the development of .NET and its ecosystem
@@ -65,7 +65,7 @@ For other issues, please file them to their appropriate sibling repos. We have l
There are many .NET related projects on GitHub.
* [.NET home repo](https://github.com/Microsoft/dotnet) - links to 100s of .NET projects, from Microsoft and the community.
-* [ASP.NET Core home](https://docs.microsoft.com/aspnet/core) - the best place to start learning about ASP.NET Core.
+* [ASP.NET Core home](https://learn.microsoft.com/aspnet/core) - the best place to start learning about ASP.NET Core.
This project has adopted the code of conduct defined by the [Contributor Covenant](https://contributor-covenant.org) to clarify expected behavior in our community. For more information, see the [.NET Foundation Code of Conduct](https://www.dotnetfoundation.org/code-of-conduct).
diff --git a/docs/README.md b/docs/README.md
index 46e859f945c6c..debc23ef00daf 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -12,7 +12,7 @@ Getting Started
===============
- [Installing the .NET SDK](https://dotnet.microsoft.com/download)
-- [Official .NET Docs](https://docs.microsoft.com/dotnet/core/)
+- [Official .NET Docs](https://learn.microsoft.com/dotnet/core/)
Workflow (Building, testing, benchmarking, profiling, etc.)
===============
@@ -69,8 +69,8 @@ Other Information
- [.NET Glossary](project/glossary.md)
- [.NET Filename Encyclopedia](project/dotnet-filenames.md)
-- [Porting to .NET Core](https://docs.microsoft.com/en-us/dotnet/standard/analyzers/portability-analyzer)
+- [Porting to .NET Core](https://learn.microsoft.com/dotnet/standard/analyzers/portability-analyzer)
- [.NET Standards (Ecma)](project/dotnet-standards.md)
- [CLR Configuration Knobs](../src/coreclr/inc/clrconfigvalues.h)
-- [CLR overview](https://docs.microsoft.com/dotnet/standard/clr)
+- [CLR overview](https://learn.microsoft.com/dotnet/standard/clr)
- [Wikipedia Entry for the CLR](https://en.wikipedia.org/wiki/Common_Language_Runtime)
diff --git a/docs/area-owners.md b/docs/area-owners.md
index cbcfb5d6b2033..a06da33480c0d 100644
--- a/docs/area-owners.md
+++ b/docs/area-owners.md
@@ -27,7 +27,7 @@ Note: Editing this file doesn't update the mapping used by `@msftbot` for area-s
| area-crossgen2-coreclr | @steveisok | @dotnet/crossgen-contrib | |
| area-Debugger-mono | @tommcdon | @thaystg | |
| area-DependencyModel | @ericstj | @dotnet/area-dependencymodel | Included:Microsoft.Extensions.DependencyModel |
-| area-Diagnostics-coreclr | @tommcdon | @tommcdon | |
+| area-Diagnostics-coreclr | @tommcdon | @tommcdon @dotnet/dotnet-diag | |
| area-Diagnostics-mono | @tommcdon | @tommcdon @mdh1418 @thaystg | |
| area-EnC-mono | @tommcdon | @mikelle-rogers @thaystg | Hot Reload on WebAssembly, Android, iOS, etc . @lambdageek to consult |
| area-ExceptionHandling-coreclr | @mangod9 | @janvorli | |
diff --git a/docs/coding-guidelines/adding-api-guidelines.md b/docs/coding-guidelines/adding-api-guidelines.md
index 2db8da8cc1f3e..f405468bac7a9 100644
--- a/docs/coding-guidelines/adding-api-guidelines.md
+++ b/docs/coding-guidelines/adding-api-guidelines.md
@@ -25,7 +25,7 @@ the implementation without compat concerns in future releases.
### Determine target framework
`net8.0` is the target framework version currently under development and the new apis
-should be added to `net8.0`. [More Information on TargetFrameworks](https://docs.microsoft.com/en-us/dotnet/standard/frameworks)
+should be added to `net8.0`. [More Information on TargetFrameworks](https://learn.microsoft.com/dotnet/standard/frameworks)
## Making the changes in repo
@@ -42,7 +42,7 @@ If your new API or the APIs it calls throw any exceptions, those need to be manu
After your change is merged, we will eventually port them to the dotnet-api-docs repo, where we will review them for language and proper style (For more information, see the [API writing guidelines](https://github.com/dotnet/dotnet-api-docs/wiki)).
-Once the dotnet-api-docs change is merged, your comments will start showing up in the official API documentation at http://docs.microsoft.com/, and later they'll appear in IntelliSense in Visual Studio and Visual Studio Code.
+Once the dotnet-api-docs change is merged, your comments will start showing up in the official API documentation at https://learn.microsoft.com, and later they'll appear in IntelliSense in Visual Studio and Visual Studio Code.
Once the documentation is official, any subsequent updates to it must be made directly in https://github.com/dotnet/dotnet-api-docs/. It's fine to make updates to the triple slash comments later, they just won't automatically flow into the official docs.
## FAQ
diff --git a/docs/coding-guidelines/api-guidelines/README.md b/docs/coding-guidelines/api-guidelines/README.md
index 31dd7181785b3..e2025c13cee98 100644
--- a/docs/coding-guidelines/api-guidelines/README.md
+++ b/docs/coding-guidelines/api-guidelines/README.md
@@ -9,5 +9,5 @@ actual [book][FDG].
To submit new proposals for design guidelines, simply create a PR adding or
modifying an existing file.
-[docs]: https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/
+[docs]: https://learn.microsoft.com/dotnet/standard/design-guidelines/
[FDG]: https://amazon.com/dp/0135896460
diff --git a/docs/coding-guidelines/clr-code-guide.md b/docs/coding-guidelines/clr-code-guide.md
index ef6f7a555d615..a5b90d7e237af 100644
--- a/docs/coding-guidelines/clr-code-guide.md
+++ b/docs/coding-guidelines/clr-code-guide.md
@@ -1028,14 +1028,14 @@ Here are some immediate tips for working well with the managed-debugging service
- Do not change behavior when under the debugger. An app should behave identically when run outside or under the debugger. This is absolutely necessary else we get complaints like "my program only crashes when run under the debugger". This is also necessary because somebody may attach a debugger to an app after the fact. Specific examples of this:
- Don't assume that just because an app is under the debugger that somebody is trying to debug it.
- Don't add additional run-time error checks when under the debugger. For example, avoid code like: if ((IsDebuggerPresent() && (argument == null)) { throw MyException(); }
- - Avoid massive perf changes when under the debugger. For example, don't use an interpreted stub just because you're under the debugger. We then get bugs like [my app is 100x slower when under a debugger](https://docs.microsoft.com/en-us/archive/blogs/jmstall/psa-pinvokes-may-be-100x-slower-under-the-debugger).
+ - Avoid massive perf changes when under the debugger. For example, don't use an interpreted stub just because you're under the debugger. We then get bugs like [my app is 100x slower when under a debugger](https://learn.microsoft.com/archive/blogs/jmstall/psa-pinvokes-may-be-100x-slower-under-the-debugger).
- Avoid algorithmic changes. For example, do not make the JIT generate non-optimized code just because an app is under the debugger. Do not make the loader policy resolve to a debuggable-ngen image just because an app is under the debugger.
- Separate your code into a) side-effect-free (non-mutating) read-only accessors and b) functions that change state. The motivation is that the debugger needs to be able to read-state in a non-invasive way. For example, don't just have GetFoo() that will lazily create a Foo if it's not available. Instead, split it out like so:
- GetFoo() - fails if a Foo does not exist. Being non-mutating, this should also be GC_NOTRIGGER. Non-mutating will also make it much easier to DAC-ize. This is what the debugger will call.
- and GetOrCreateFoo() that is built around GetFoo(). The rest of the runtime can call this.
- The debugger can then just call GetFoo(), and deal with the failure accordingly.
- If you add a new stub (or way to call managed code), make sure that you can source-level step-in (F11) it under the debugger. The debugger is not psychic. A source-level step-in needs to be able to go from the source-line before a call to the source-line after the call, or managed code developers will be very confused. If you make that call transition be a giant 500 line stub, you must cooperate with the debugger for it to know how to step-through it. (This is what StubManagers are all about. See [src\vm\stubmgr.h](https://github.com/dotnet/runtime/blob/main/src/coreclr/vm/stubmgr.h)). Try doing a step-in through your new codepath under the debugger.
-- **Beware of timeouts** : The debugger may completely suspend your process at arbitrary points. In most cases, the debugger will do the right thing (and suspend your timeout too), but not always. For example, if you have some other process waiting for info from the debuggee, it [may hit a timeout](https://docs.microsoft.com/en-us/archive/blogs/jmstall/why-you-sometimes-get-a-bogus-contextswitchdeadlock-mda-under-the-debugger).
+- **Beware of timeouts** : The debugger may completely suspend your process at arbitrary points. In most cases, the debugger will do the right thing (and suspend your timeout too), but not always. For example, if you have some other process waiting for info from the debuggee, it [may hit a timeout](https://learn.microsoft.com/archive/blogs/jmstall/why-you-sometimes-get-a-bogus-contextswitchdeadlock-mda-under-the-debugger).
- **Use CLR synchronization primitives (like Crst)**. In addition to all the reasons listed in the synchronization section, the CLR-aware primitives can cooperate with the debugging services. For example:
- The debugger needs to know when threads are modifying sensitive data (which correlates to when the threads lock that data).
- Timeouts for CLR synchronization primitives may operate better in the face of being debugged.
diff --git a/docs/coding-guidelines/framework-design-guidelines-digest.md b/docs/coding-guidelines/framework-design-guidelines-digest.md
index ff2ce139977c4..d48ecc60727dc 100644
--- a/docs/coding-guidelines/framework-design-guidelines-digest.md
+++ b/docs/coding-guidelines/framework-design-guidelines-digest.md
@@ -308,5 +308,5 @@ conformance to the [Framework Design Guidelines][FDG] (also see [MSDN](https://m
## Presentations
-* [Overview of the Framework Design Guidelines](https://docs.microsoft.com/en-us/archive/blogs/kcwalina/online-lecture-on-api-design)
-* [TechEd 2007 Presentation about framework engineering](https://docs.microsoft.com/en-us/archive/blogs/kcwalina/video-recording-of-framework-engineering-architecting-designing-and-developing-reusable-libraries)
+* [Overview of the Framework Design Guidelines](https://learn.microsoft.com/archive/blogs/kcwalina/online-lecture-on-api-design)
+* [TechEd 2007 Presentation about framework engineering](https://learn.microsoft.com/archive/blogs/kcwalina/video-recording-of-framework-engineering-architecting-designing-and-developing-reusable-libraries)
diff --git a/docs/coding-guidelines/interop-guidelines.md b/docs/coding-guidelines/interop-guidelines.md
index b755f3cd74ec7..8338f4c1d04e2 100644
--- a/docs/coding-guidelines/interop-guidelines.md
+++ b/docs/coding-guidelines/interop-guidelines.md
@@ -1,7 +1,7 @@
Interop Guidelines
==================
-We follow the [best practices for native interop](https://learn.microsoft.com/en-us/dotnet/standard/native-interop/best-practices) with the additional guidelines below that are specific to this repo.
+We follow the [best practices for native interop](https://learn.microsoft.com/dotnet/standard/native-interop/best-practices) with the additional guidelines below that are specific to this repo.
## Goals
We have the following goals related to interop code being used in dotnet/runtime:
@@ -166,7 +166,7 @@ Using enums instead of partial, static classes can lead to needing lots of casts
## P/Invoke Definitions
-When defining the P/Invoke signatures and structs, we follow the guidelines in the [interop best practices documentation](https://docs.microsoft.com/en-us/dotnet/standard/native-interop/best-practices).
+When defining the P/Invoke signatures and structs, we follow the guidelines in the [interop best practices documentation](https://learn.microsoft.com/dotnet/standard/native-interop/best-practices).
The runtime repo makes use of [source-generated p/invokes](../design/features/source-generator-pinvokes.md) whenever possible (see [the compatibility doc](../design/libraries/LibraryImportGenerator/Compatibility.md) for unsupported scenarios). Methods should be marked `LibraryImport` and be `static` and `partial`.
diff --git a/docs/coding-guidelines/libraries-packaging.md b/docs/coding-guidelines/libraries-packaging.md
index f7c926890bf8e..61829fe545982 100644
--- a/docs/coding-guidelines/libraries-packaging.md
+++ b/docs/coding-guidelines/libraries-packaging.md
@@ -46,7 +46,7 @@ Most metadata for packages is controlled centrally in the repository and individ
Logging abstractions for Microsoft.Extensions.Logging.
```
-Package content can be defined using any of the publicly defined Pack inputs: https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets
+Package content can be defined using any of the publicly defined Pack inputs: https://learn.microsoft.com/nuget/reference/msbuild-targets
### Package Readme
diff --git a/docs/design/coreclr/botr/clr-abi.md b/docs/design/coreclr/botr/clr-abi.md
index 417f6fdec5346..1347b2c0c6b20 100644
--- a/docs/design/coreclr/botr/clr-abi.md
+++ b/docs/design/coreclr/botr/clr-abi.md
@@ -14,11 +14,11 @@ Read everything in the documented Windows and non-Windows ABI documentation. The
## Windows ABI documentation
-AMD64: See [x64 Software Conventions](https://docs.microsoft.com/en-us/cpp/build/x64-software-conventions).
+AMD64: See [x64 Software Conventions](https://learn.microsoft.com/cpp/build/x64-software-conventions).
-ARM: See [Overview of ARM32 ABI Conventions](https://docs.microsoft.com/en-us/cpp/build/overview-of-arm-abi-conventions).
+ARM: See [Overview of ARM32 ABI Conventions](https://learn.microsoft.com/cpp/build/overview-of-arm-abi-conventions).
-ARM64: See [Overview of ARM64 ABI conventions](https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions).
+ARM64: See [Overview of ARM64 ABI conventions](https://learn.microsoft.com/cpp/build/arm64-windows-abi-conventions).
## Non-Windows ABI documentation
diff --git a/docs/design/coreclr/botr/corelib.md b/docs/design/coreclr/botr/corelib.md
index c5ff7f387e83f..9662dc3f4e20f 100644
--- a/docs/design/coreclr/botr/corelib.md
+++ b/docs/design/coreclr/botr/corelib.md
@@ -40,7 +40,7 @@ The CLR provides a [`mscorlib` binder](https://github.com/dotnet/runtime/blob/ma
# Calling from managed to native code
-Two techniques exist for calling into the CLR from managed code. FCall allows you to call directly into the CLR code, and provides a lot of flexibility in terms of manipulating objects, though it is easy to cause GC holes by not tracking object references correctly. QCall also allows you to call into the CLR via the P/Invoke, but is much harder to accidentally mis-use. FCalls are identified in managed code as extern methods with the [`MethodImplOptions.InternalCall`](https://docs.microsoft.com/dotnet/api/system.runtime.compilerservices.methodimploptions) bit set. QCalls are marked `static extern` methods similar to regular P/Invokes, but are directed toward a library called `"QCall"`.
+Two techniques exist for calling into the CLR from managed code. FCall allows you to call directly into the CLR code, and provides a lot of flexibility in terms of manipulating objects, though it is easy to cause GC holes by not tracking object references correctly. QCall also allows you to call into the CLR via the P/Invoke, but is much harder to accidentally mis-use. FCalls are identified in managed code as extern methods with the [`MethodImplOptions.InternalCall`](https://learn.microsoft.com/dotnet/api/system.runtime.compilerservices.methodimploptions) bit set. QCalls are marked `static extern` methods similar to regular P/Invokes, but are directed toward a library called `"QCall"`.
There is a small variant of FCall called HCall (for Helper call) for implementing JIT helpers. The HCall is intended for doing things like accessing multi-dimensional array elements, range checks, etc. The only difference between HCall and FCall is that HCall methods won't show up in an exception stack trace.
@@ -50,13 +50,13 @@ First, remember that you should be writing as much as possible in managed code.
Reasons to write FCalls in the past generally fell into three camps: missing language features, better performance, or implementing unique interactions with the runtime. C# now has almost every useful language feature that you could get from C++, including unsafe code and stack-allocated buffers, and this eliminates the first two reasons for FCalls. We have ported some parts of the CLR that were heavily reliant on FCalls to managed code in the past (such as Reflection, some Encoding, and String operations) and we intend to continue this momentum.
-If the only reason you're defining a FCall method is to call a native method, you should be using P/Invoke to call the method directly. [P/Invoke](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute) is the public native method interface and should be doing everything you need in a correct manner.
+If the only reason you're defining a FCall method is to call a native method, you should be using P/Invoke to call the method directly. [P/Invoke](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute) is the public native method interface and should be doing everything you need in a correct manner.
If you still need to implement a feature inside the runtime, consider if there is a way to reduce the frequency of transitioning to native code. Can you write the common case in managed and only call into native for some rare corner cases? You're usually best off keeping as much as possible in managed code.
QCalls are the preferred mechanism going forward. You should only use FCalls when you are "forced" to. This happens when there is common "short path" through the code that is important to optimize. This short path should not be more than a few hundred instructions, cannot allocate GC memory, take locks or throw exceptions (`GC_NOTRIGGER`, `NOTHROWS`). In all other circumstances (and especially when you enter a FCall and then simply erect HelperMethodFrame), you should be using QCall.
-FCalls were specifically designed for short paths of code that must be optimized. They allowed explicit control over when erecting a frame was done. However, it is error prone and not worth the complexity for many APIs. QCalls are essentially P/Invokes into the CLR. In the event the performance of an FCall is required consider creating a QCall and marking it with [`SuppressGCTransitionAttribute`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.suppressgctransitionattribute).
+FCalls were specifically designed for short paths of code that must be optimized. They allowed explicit control over when erecting a frame was done. However, it is error prone and not worth the complexity for many APIs. QCalls are essentially P/Invokes into the CLR. In the event the performance of an FCall is required consider creating a QCall and marking it with [`SuppressGCTransitionAttribute`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.suppressgctransitionattribute).
As a result, QCalls give you some advantageous marshaling for `SafeHandle`s automatically – your native method just takes a `HANDLE` type, and can be used without worrying whether someone will free the handle while in that method body. The resulting FCall method would need to use a `SafeHandleHolder` and may need to protect the `SafeHandle`, etc. Leveraging the P/Invoke marshaler can avoid this additional plumbing code.
diff --git a/docs/design/coreclr/botr/guide-for-porting.md b/docs/design/coreclr/botr/guide-for-porting.md
index f7ca105bf165d..25c0aae0e068f 100644
--- a/docs/design/coreclr/botr/guide-for-porting.md
+++ b/docs/design/coreclr/botr/guide-for-porting.md
@@ -181,7 +181,7 @@ both the JIT and VM.
2. Architecture specific relocation information (to represent generation of
relocations for use by load, store, jmp and call instructions) See
-
+
for the sort of details that need to be defined.
3. Behavior and accessibility of processor single step features from within a
diff --git a/docs/design/coreclr/jit/viewing-jit-dumps.md b/docs/design/coreclr/jit/viewing-jit-dumps.md
index d24611be40211..7d459895f9ae1 100644
--- a/docs/design/coreclr/jit/viewing-jit-dumps.md
+++ b/docs/design/coreclr/jit/viewing-jit-dumps.md
@@ -115,7 +115,7 @@ For example, for Windows x64 machine, the project file is:
```
- You can find a list of RIDs and their corresponding OSes [here](https://docs.microsoft.com/en-us/dotnet/articles/core/rid-catalog).
+ You can find a list of RIDs and their corresponding OSes [here](https://learn.microsoft.com/dotnet/articles/core/rid-catalog).
* After you've finished editing the code, run `dotnet restore` and `dotnet publish -c Release`. This should drop all of the binaries needed to run your app in `bin/Release///publish`.
* Overwrite the CLR dlls with the ones you've built locally. If you're a fan of the command line, here are some shell commands for doing this:
diff --git a/docs/design/coreclr/profiling/davbr-blog-archive/Debugging - Activation.md b/docs/design/coreclr/profiling/davbr-blog-archive/Debugging - Activation.md
index 327c90451b9c2..6a3e3b01572fb 100644
--- a/docs/design/coreclr/profiling/davbr-blog-archive/Debugging - Activation.md
+++ b/docs/design/coreclr/profiling/davbr-blog-archive/Debugging - Activation.md
@@ -1,7 +1,7 @@
*This blog post originally appeared on David Broman's blog on 12/11/2007*
-This is the first of some tips to help you debug your profiler. Note that these tips assume you're using CLR 2.x (see [this entry](https://docs.microsoft.com/en-us/archive/blogs/davbr/versions-of-microsoft-net-framework-clr-and-your-profiler) for info on how CLR version numbers map to .NET Framework version numbers). In today's post, I address a frequent question from profiler developers and users: "Why didn't my profiler load?".
+This is the first of some tips to help you debug your profiler. Note that these tips assume you're using CLR 2.x (see [this entry](https://learn.microsoft.com/archive/blogs/davbr/versions-of-microsoft-net-framework-clr-and-your-profiler) for info on how CLR version numbers map to .NET Framework version numbers). In today's post, I address a frequent question from profiler developers and users: "Why didn't my profiler load?".
## Event log (Windows only)
diff --git a/docs/design/coreclr/profiling/davbr-blog-archive/ELT Hooks - tail calls.md b/docs/design/coreclr/profiling/davbr-blog-archive/ELT Hooks - tail calls.md
index d00ceba195e7c..7518db43102d4 100644
--- a/docs/design/coreclr/profiling/davbr-blog-archive/ELT Hooks - tail calls.md
+++ b/docs/design/coreclr/profiling/davbr-blog-archive/ELT Hooks - tail calls.md
@@ -55,7 +55,7 @@ When you're dealing with languages managed by the CLR, there are two kinds of co
### When does the JIT make tail calls?
-I asked Fei Chen and [Grant Richins](https://docs.microsoft.com/en-us/archive/blogs/grantri/), neighbors down the hall from me who happen to work on the JIT, under what conditions the various JITs will employ the tail call optimization. The full answer is rather detailed. The quick summary is that the JITs try to use the tail call optimization whenever they can, but there are lots of reasons why the tail call optimization can't be used. Some reasons why tail calling is a non-option:
+I asked Fei Chen and [Grant Richins](https://learn.microsoft.com/archive/blogs/grantri/), neighbors down the hall from me who happen to work on the JIT, under what conditions the various JITs will employ the tail call optimization. The full answer is rather detailed. The quick summary is that the JITs try to use the tail call optimization whenever they can, but there are lots of reasons why the tail call optimization can't be used. Some reasons why tail calling is a non-option:
- Caller doesn't return immediately after the call (duh :-))
- Stack arguments between caller and callee are incompatible in a way that would require shifting things around in the caller's frame before the callee could execute
diff --git a/docs/design/coreclr/profiling/davbr-blog-archive/Generics and Your Profiler.md b/docs/design/coreclr/profiling/davbr-blog-archive/Generics and Your Profiler.md
index 856290fd99311..fce6538b6eb97 100644
--- a/docs/design/coreclr/profiling/davbr-blog-archive/Generics and Your Profiler.md
+++ b/docs/design/coreclr/profiling/davbr-blog-archive/Generics and Your Profiler.md
@@ -83,7 +83,7 @@ typeArgs: This is the array of type arguments used to instantiate classId, which
You may have noticed I ignored this parameter in my description of GetFunctionInfo2. You can pass NULL if you want, and nothing really bad will happen to you, but you’ll often get some incomplete results: you won’t get very useful typeArgs coming back, and you’ll often see NULL returned in \*pClassId.
-To understand why, it’s necessary to understand an internal optimization the CLR uses around sharing code for generics: If two instantiations of the same generic function would result in identical JITted code, then why not have them share one copy of that code? The CLR chooses to share code if all of the type parameters are instantiated with reference types. If you want to read more about this, [here’s](https://docs.microsoft.com/en-us/archive/blogs/carlos/net-generics-and-code-bloat-or-its-lack-thereof) a place to go.
+To understand why, it’s necessary to understand an internal optimization the CLR uses around sharing code for generics: If two instantiations of the same generic function would result in identical JITted code, then why not have them share one copy of that code? The CLR chooses to share code if all of the type parameters are instantiated with reference types. If you want to read more about this, [here’s](https://learn.microsoft.com/archive/blogs/carlos/net-generics-and-code-bloat-or-its-lack-thereof) a place to go.
For now, the important point is that, once we’re inside JITted code that is shared across different generic instantiations, how can one know which instantiation is the actual one that caused the current invocation? Well, in many cases, the CLR may not have that data readily lying around. However, as a profiler, you can capture this information and pass it back to the CLR when it needs it. This is done through a COR\_PRF\_FRAME\_INFO. There are two ways your profiler can get a COR\_PRF\_FRAME\_INFO:
@@ -110,7 +110,7 @@ CLR’s generics sharing optimization complicates this somewhat. You’ll reall
So that covers JIT notifications—what about ClassLoad\* notifications in the same example? Although the CLR shares _JITted code_ across reference-type instantiations, the CLR still maintains separate loaded _types_ for each generic instantiation of a generic class. So in the example from the paragraph above you will see separate ClassLoad\* notifications with different ClassIDs for MyClass\ and MyClass\. In fact, you will also see a separate ClassLoad\* notification (with yet another ClassID) for MyClass\.
-If you got curious, and ran such a profiler under the debugger, you could use the SOS !dumpmt command with those different ClassIDs to see what you get. By doing so, you’ll notice something interesting. !dumpmt shows many values, including “Name”, which will correctly be the specific, fully-instantiated name of the type (different for all three ClassIDs). !dumpmt also shows a thing called “EEClass”. And you’ll notice this “EEClass” value is actually the _same_ for all 3 types. (Remember from this [post](https://docs.microsoft.com/en-us/archive/blogs/davbr/debugging-your-profiler-ii-sos-and-ids) that EEClass is NOT the same thing as ClassID!) That gives you a little window into some additional data sharing optimizations the CLR uses. Stuff that remains the same across different generic instantiations of a class can be stored in a single place (the EEClass) and that single place can be referenced by the different generic instantiations of the class. Note that if you also use a value type as the type argument when instantiating MyClass\ (e.g., MyClass\), and then run !dumpmt on that ClassID, you’ll see an entirely different EEClass value in the output, as the CLR will not be sharing that subset of type data across generic instantiations that use type arguments that are value types.
+If you got curious, and ran such a profiler under the debugger, you could use the SOS !dumpmt command with those different ClassIDs to see what you get. By doing so, you’ll notice something interesting. !dumpmt shows many values, including “Name”, which will correctly be the specific, fully-instantiated name of the type (different for all three ClassIDs). !dumpmt also shows a thing called “EEClass”. And you’ll notice this “EEClass” value is actually the _same_ for all 3 types. (Remember from this [post](https://learn.microsoft.com/archive/blogs/davbr/debugging-your-profiler-ii-sos-and-ids) that EEClass is NOT the same thing as ClassID!) That gives you a little window into some additional data sharing optimizations the CLR uses. Stuff that remains the same across different generic instantiations of a class can be stored in a single place (the EEClass) and that single place can be referenced by the different generic instantiations of the class. Note that if you also use a value type as the type argument when instantiating MyClass\ (e.g., MyClass\), and then run !dumpmt on that ClassID, you’ll see an entirely different EEClass value in the output, as the CLR will not be sharing that subset of type data across generic instantiations that use type arguments that are value types.
## Instrumenting Generic Functions
diff --git a/docs/design/coreclr/profiling/davbr-blog-archive/Sample A Signature Blob Parser for your Profiler.md b/docs/design/coreclr/profiling/davbr-blog-archive/Sample A Signature Blob Parser for your Profiler.md
index 88ab78844b3da..5d9215222f593 100644
--- a/docs/design/coreclr/profiling/davbr-blog-archive/Sample A Signature Blob Parser for your Profiler.md
+++ b/docs/design/coreclr/profiling/davbr-blog-archive/Sample A Signature Blob Parser for your Profiler.md
@@ -1,7 +1,7 @@
*This blog post originally appeared on David Broman's blog on 10/13/2005*
-If your profiler plays with metadata, you've undoubtedly come across signature blobs. They’re used to encode type information for method definitions & references, local variables, and a whole lot more. They’re wonderfully compact, recursively versatile, and sometimes, well, challenging to parse. Fortunately, [Rico Mariani](https://docs.microsoft.com/en-us/archive/blogs/ricom/) was feeling generous one day, and churned out a simple parser that can read these types of signatures:
+If your profiler plays with metadata, you've undoubtedly come across signature blobs. They’re used to encode type information for method definitions & references, local variables, and a whole lot more. They’re wonderfully compact, recursively versatile, and sometimes, well, challenging to parse. Fortunately, [Rico Mariani](https://learn.microsoft.com/archive/blogs/ricom/) was feeling generous one day, and churned out a simple parser that can read these types of signatures:
- MethodDefSig
- MethodRefSig
diff --git a/docs/design/datacontracts/Thread.md b/docs/design/datacontracts/Thread.md
index 2910dc8dbb820..92382eacf32d5 100644
--- a/docs/design/datacontracts/Thread.md
+++ b/docs/design/datacontracts/Thread.md
@@ -2,15 +2,16 @@
This contract is for reading and iterating the threads of the process.
-## Data structures defined by contract
+## APIs of contract
+
``` csharp
-record struct DacThreadStoreData (
+record struct ThreadStoreData (
int ThreadCount,
TargetPointer FirstThread,
TargetPointer FinalizerThread,
TargetPointer GcThread);
-record struct DacThreadStoreCounts (
+record struct ThreadStoreCounts (
int UnstartedThreadCount,
int BackgroundThreadCount,
int PendingThreadCount,
@@ -75,7 +76,7 @@ enum ThreadState
TS_Detached = 0x80000000, // Thread was detached by DllMain
}
-record struct DacThreadData (
+record struct ThreadData (
uint ThreadId;
TargetNUint OsThreadId;
ThreadState State;
@@ -90,11 +91,10 @@ record struct DacThreadData (
);
```
-## Apis of contract
``` csharp
-DacThreadStoreData GetThreadStoreData();
-DacThreadStoreCounts GetThreadCounts();
-DacThreadData GetThreadData(TargetPointer threadPointer);
+ThreadStoreData GetThreadStoreData();
+ThreadStoreCounts GetThreadCounts();
+ThreadData GetThreadData(TargetPointer threadPointer);
TargetPointer GetNestedExceptionInfo(TargetPointer nestedExceptionPointer, out TargetPointer nextNestedException);
TargetPointer GetManagedThreadObject(TargetPointer threadPointer);
```
@@ -106,26 +106,26 @@ TargetPointer GetManagedThreadObject(TargetPointer threadPointer);
``` csharp
SListReader ThreadListReader = Contracts.SList.GetReader("Thread");
-DacThreadStoreData GetThreadStoreData()
+ThreadStoreData GetThreadStoreData()
{
- TargetPointer threadStore = Target.ReadGlobalTargetPointer("s_pThreadStore");
+ TargetPointer threadStore = Target.ReadGlobalPointer("s_pThreadStore");
var runtimeThreadStore = new ThreadStore(Target, threadStore);
TargetPointer firstThread = ThreadListReader.GetHead(runtimeThreadStore.SList.Pointer);
- return new DacThreadStoreData(
+ return new ThreadStoreData(
ThreadCount : runtimeThreadStore.m_ThreadCount,
FirstThread: firstThread,
- FinalizerThread: Target.ReadGlobalTargetPointer("g_pFinalizerThread"),
- GcThread: Target.ReadGlobalTargetPointer("g_pSuspensionThread"));
+ FinalizerThread: Target.ReadGlobalPointer("g_pFinalizerThread"),
+ GCThread: Target.ReadGlobalPointer("g_pSuspensionThread"));
}
DacThreadStoreCounts GetThreadCounts()
{
- TargetPointer threadStore = Target.ReadGlobalTargetPointer("s_pThreadStore");
+ TargetPointer threadStore = Target.ReadGlobalPointer("s_pThreadStore");
var runtimeThreadStore = new ThreadStore(Target, threadStore);
- return new DacThreadStoreCounts(
+ return new ThreadStoreCounts(
ThreadCount : runtimeThreadStore.m_ThreadCount,
UnstartedThreadCount : runtimeThreadStore.m_UnstartedThreadCount,
BackgroundThreadCount : runtimeThreadStore.m_BackgroundThreadCount,
@@ -133,7 +133,7 @@ DacThreadStoreCounts GetThreadCounts()
DeadThreadCount: runtimeThreadStore.m_DeadThreadCount,
}
-DacThreadData GetThreadData(TargetPointer threadPointer)
+ThreadData GetThreadData(TargetPointer threadPointer)
{
var runtimeThread = new Thread(Target, threadPointer);
@@ -150,7 +150,7 @@ DacThreadData GetThreadData(TargetPointer threadPointer)
firstNestedException = runtimeThread.m_ExceptionState.m_currentExInfo.m_pPrevNestedInfo;
}
- return new DacThread(
+ return new ThreadData(
ThreadId : runtimeThread.m_ThreadId,
OsThreadId : (OsThreadId)runtimeThread.m_OSThreadId,
State : (ThreadState)runtimeThread.m_State,
@@ -159,7 +159,7 @@ DacThreadData GetThreadData(TargetPointer threadPointer)
AllocContextLimit : thread.m_alloc_context.alloc_limit,
Frame : thread.m_pFrame,
TEB : thread.Has_m_pTEB ? thread.m_pTEB : TargetPointer.Null,
- LastThreadObjectHandle : new DacGCHandle(thread.m_LastThrownObjectHandle),
+ LastThrownObjectHandle : new DacGCHandle(thread.m_LastThrownObjectHandle),
FirstNestedException : firstNestedException,
NextThread : ThreadListReader.GetHead.GetNext(threadPointer)
);
diff --git a/docs/design/datacontracts/contract_csharp_api_design.cs b/docs/design/datacontracts/contract_csharp_api_design.cs
index 062c04806003c..a770c1f4576b4 100644
--- a/docs/design/datacontracts/contract_csharp_api_design.cs
+++ b/docs/design/datacontracts/contract_csharp_api_design.cs
@@ -40,7 +40,7 @@ struct TargetPointer
struct TargetNInt
{
public long Value;
- // Add a full set of operators to support arithmetic as well as casting to/from TargetPointer
+ // Add a full set of operators to support arithmetic as well as casting to/from TargetPointer
}
struct TargetNUInt
@@ -72,84 +72,37 @@ struct FieldLayout
public FieldType Type;
}
- interface IAlgorithmContract
- {
- void Init();
- }
-
interface IContract
{
string Name { get; }
uint Version { get; }
}
- class Target
+
+ sealed class Target
{
// Users of the data contract may adjust this number to force re-reading of all data
public int CurrentEpoch = 0;
- sbyte ReadInt8(TargetPointer pointer);
- byte ReadUInt8(TargetPointer pointer);
- short ReadInt16(TargetPointer pointer);
- ushort ReadUInt16(TargetPointer pointer);
- int ReadInt32(TargetPointer pointer);
- uint ReadUInt32(TargetPointer pointer);
- long ReadInt64(TargetPointer pointer);
- ulong ReadUInt64(TargetPointer pointer);
- TargetPointer ReadTargetPointer(TargetPointer pointer);
- TargetNInt ReadNInt(TargetPointer pointer);
- TargetNUInt ReadNUint(TargetPointer pointer);
+ public T Read(ulong address) where T : unmanaged, IBinaryInteger, IMinMaxValue;
+ TargetPointer ReadPointer(ulong address);
+
byte[] ReadByteArray(TargetPointer pointer, ulong size);
void FillByteArray(TargetPointer pointer, byte[] array, ulong size);
- bool TryReadInt8(TargetPointer pointer, out sbyte value);
- bool TryReadUInt8(TargetPointer pointer, out byte value);
- bool TryReadInt16(TargetPointer pointer, out short value);
- bool TryReadUInt16(TargetPointer pointer, out ushort value);
- bool TryReadInt32(TargetPointer pointer, out int value);
- bool TryReadUInt32(TargetPointer pointer, out uint value);
- bool TryReadInt64(TargetPointer pointer, out long value);
- bool TryReadUInt64(TargetPointer pointer, out ulong value);
- bool TryReadTargetPointer(TargetPointer pointer, out TargetPointer value);
- bool TryReadNInt(TargetPointer pointer, out TargetNInt value);
- bool TryReadNUInt(TargetPointer pointer, out TargetNUInt value);
- bool TryReadByteArray(TargetPointer pointer, ulong size, out byte[] value);
- bool TryFillByteArray(TargetPointer pointer, byte[] array, ulong size);
-
// If pointer is 0, then the return value will be 0
TargetPointer GetTargetPointerForField(TargetPointer pointer, FieldLayout fieldLayout);
- sbyte ReadGlobalInt8(string globalName);
- byte ReadGlobalUInt8(string globalName);
- short ReadGlobalInt16(string globalName);
- ushort ReadGlobalUInt16(string globalName);
- int ReadGlobalInt32(string globalName);
- uint ReadGlobalUInt32(string globalName);
- long ReadGlobalInt64(string globalName);
- ulong ReadGlobalUInt64(string globalName);
- TargetPointer ReadGlobalTargetPointer(string globalName);
-
- bool TryReadGlobalInt8(string globalName, out sbyte value);
- bool TryReadGlobalUInt8(string globalName, out byte value);
- bool TryReadGlobalInt16(string globalName, out short value);
- bool TryReadGlobalUInt16(string globalName, out ushort value);
- bool TryReadGlobalInt32(string globalName, out int value);
- bool TryReadGlobalUInt32(string globalName, out uint value);
- bool TryReadGlobalInt64(string globalName, out long value);
- bool TryReadGlobalUInt64(string globalName, out ulong value);
- bool TryReadGlobalTargetPointer(string globalName, out TargetPointer value);
-
- Contracts Contract { get; }
-
- partial class Contracts
- {
- FieldLayout GetFieldLayout(string typeName, string fieldName);
- bool TryGetFieldLayout(string typeName, string fieldName, out FieldLayout layout);
- int GetTypeSize(string typeName);
- bool TryGetTypeSize(string typeName, out int size);
+ T ReadGlobal(string globalName) where T : unmanaged, IBinaryInteger, IMinMaxValue;
+ TargetPointer ReadGlobalPointer(string globalName);
- object GetContract(string contractName);
- bool TryGetContract(string contractName, out object contract);
+ Contracts.Registry Contracts { get; }
+ }
+ // Types defined by contracts live here
+ namespace Contracts
+ {
+ class Registry
+ {
// Every contract that is defined has a field here. As an example this document defines a MethodTableContract
// If the contract is not supported by the runtime in use, then the implementation of the contract will be the base type which
// is defined to throw if it is ever used.
@@ -157,15 +110,6 @@ partial class Contracts
// List of contracts will be inserted here by source generator
MethodTableContract MethodTableContract;
}
- }
-
- // Types defined by contracts live here
- namespace ContractDefinitions
- {
- class CompositeContract
- {
- List> Subcontracts;
- }
class DataStructureContract
{
@@ -173,8 +117,8 @@ class DataStructureContract
List> FieldData;
}
- // Insert Algorithmic Contract definitions here
- class MethodTableContract
+ // Insert contract definitions here
+ interface MethodTableContract : IContract
{
public virtual int DynamicTypeID(TargetPointer methodTablePointer) { throw new NotImplementedException(); }
public virtual int BaseSize(TargetPointer methodTablePointer) { throw new NotImplementedException(); }
@@ -207,7 +151,7 @@ public class FeatureFlags_2
}
[DataContractAlgorithm(1)]
- class MethodTableContract_1 : ContractDefinitions.MethodTableContract, IAlgorithmContract
+ readonly struct MethodTableContract_1 : Contracts.MethodTableContract
{
DataContracts.Target Target;
readonly uint ContractVersion;
@@ -219,7 +163,7 @@ class MethodTableContract_1 : ContractDefinitions.MethodTableContract, IAlgorith
// This is used for version 2 and 3 of the contract, where the dynamic type id is no longer present, and baseSize has a new limitation in that it can only be a value up to 0x1FFFFFFF in v3
[DataContractAlgorithm(2, 3)]
- class MethodTableContract_2 : ContractDefinitions.MethodTableContract, IAlgorithmContract
+ readonly struct MethodTableContract_2 : Contracts.MethodTableContract
{
DataContracts.Target Target;
readonly uint ContractVersion;
diff --git a/docs/design/features/COM-activation.md b/docs/design/features/COM-activation.md
index 866359ab1802d..d7f6a71cc705f 100644
--- a/docs/design/features/COM-activation.md
+++ b/docs/design/features/COM-activation.md
@@ -2,7 +2,7 @@
## Purpose
-In order to more fully support the vast number of existing .NET Framework users in their transition to .NET Core, support of the COM activation scenario in .NET Core is required. Without this support it is not possible for many .NET Framework consumers to even consider transitioning to .NET Core. The intent of this document is to describe aspects of COM activation for a .NET class written for .NET Core. This support includes but is not limited to activation scenarios such as the [`CoCreateInstance()`](https://docs.microsoft.com/windows/desktop/api/combaseapi/nf-combaseapi-cocreateinstance) API in C/C++ or from within a [Windows Script Host](https://docs.microsoft.com/windows/desktop/com/using-com-objects-in-windows-script-host) instance.
+In order to more fully support the vast number of existing .NET Framework users in their transition to .NET Core, support of the COM activation scenario in .NET Core is required. Without this support it is not possible for many .NET Framework consumers to even consider transitioning to .NET Core. The intent of this document is to describe aspects of COM activation for a .NET class written for .NET Core. This support includes but is not limited to activation scenarios such as the [`CoCreateInstance()`](https://learn.microsoft.com/windows/desktop/api/combaseapi/nf-combaseapi-cocreateinstance) API in C/C++ or from within a [Windows Script Host](https://learn.microsoft.com/windows/desktop/com/using-com-objects-in-windows-script-host) instance.
COM activation in this document is currently limited to in-proc scenarios. Scenarios involving out-of-proc COM activation are deferred.
@@ -10,7 +10,7 @@ COM activation in this document is currently limited to in-proc scenarios. Scena
* Discover all installed versions of .NET Core.
* Load the appropriate version of .NET Core for the class if a .NET Core instance is not running, or validate the currently existing .NET Core instance can satisfy the class requirement.
-* Return an [`IClassFactory`](https://docs.microsoft.com/windows/desktop/api/unknwnbase/nn-unknwnbase-iclassfactory) implementation that will construct an instance of the .NET class.
+* Return an [`IClassFactory`](https://learn.microsoft.com/windows/desktop/api/unknwnbase/nn-unknwnbase-iclassfactory) implementation that will construct an instance of the .NET class.
* Support the discrimination of concurrently loaded CLR versions.
### Environment matrix
@@ -35,7 +35,7 @@ One of the basic issues with the activation of a .NET class within a COM environ
The .NET Framework uses a shim library (`mscoree.dll`) to facilitate the loading of the CLR into a process performing activation - one of the many uses of `mscoree.dll`. When .NET Framework 4.0 was released, `mscoreei.dll` was introduced to provide a level of indirection between the system installed shim (`mscoree.dll`) and a specific framework shim as well as to enable side-by-side CLR scenarios. An important consideration of the system wide shim is that of servicing. Servicing `mscoree.dll` is difficult since any process with a loaded .NET Framework instance will have the shim loaded, thus requiring a system reboot in order to service the shim.
-During .NET class registration, the shim is identified as the in-proc server for the class. Additional metadata is inserted into the registry to indicate what .NET assembly to load and what type to activate. For example, in addition to the typical [in-proc server](https://docs.microsoft.com/windows/desktop/com/inprocserver32) registry values the following values are added to the registry for the `TypeLoadException` class.
+During .NET class registration, the shim is identified as the in-proc server for the class. Additional metadata is inserted into the registry to indicate what .NET assembly to load and what type to activate. For example, in addition to the typical [in-proc server](https://learn.microsoft.com/windows/desktop/com/inprocserver32) registry values the following values are added to the registry for the `TypeLoadException` class.
```
"Assembly"="mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
@@ -43,7 +43,7 @@ During .NET class registration, the shim is identified as the in-proc server for
"RuntimeVersion"="v1.1.4322"
```
-The above registration is typically done with the [`RegAsm.exe`](https://docs.microsoft.com/dotnet/framework/tools/regasm-exe-assembly-registration-tool) tool. Alternatively, registry scripts can be generated by `RegAsm.exe`.
+The above registration is typically done with the [`RegAsm.exe`](https://learn.microsoft.com/dotnet/framework/tools/regasm-exe-assembly-registration-tool) tool. Alternatively, registry scripts can be generated by `RegAsm.exe`.
### .NET Core class COM activation
@@ -51,9 +51,9 @@ In .NET Core, our intent will be to avoid a system wide shim library. This decis
The current .NET Core hosting solutions are described in detail at [Documentation/design-docs/host-components.md](https://github.com/dotnet/runtime/tree/main/docs/design/features/host-components.md). Along with the existing hosts an additional customizable COM activation host library (`comhost.dll`) will be added. This library (henceforth identified as 'shim') will export the required functions for COM class activation and registration and act in a way similar to .NET Framework's `mscoree.dll`.
->[`HRESULT DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv);`](https://docs.microsoft.com/windows/desktop/api/combaseapi/nf-combaseapi-dllgetclassobject)
+>[`HRESULT DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv);`](https://learn.microsoft.com/windows/desktop/api/combaseapi/nf-combaseapi-dllgetclassobject)
->[`HRESULT DllCanUnloadNow();`](https://docs.microsoft.com/windows/desktop/api/combaseapi/nf-combaseapi-dllcanunloadnow)
+>[`HRESULT DllCanUnloadNow();`](https://learn.microsoft.com/windows/desktop/api/combaseapi/nf-combaseapi-dllcanunloadnow)
>[`HRESULT DllRegisterServer();`](https://msdn.microsoft.com/library/windows/desktop/ms682162(v=vs.85).aspx)
@@ -63,7 +63,7 @@ When `DllGetClassObject()` is called in a COM activation scenario, the following
1) Determine additional registration information needed for activation.
* The shim will check for an embedded manifest. If the shim does not contain an embedded manifest, the shim will check if a file with the `.clsidmap` naming format exists adjacent to it. Build tooling handles shim customization, including renaming the shim to be based on the managed assembly's name (e.g. `NetComServer.dll` will have a custom shim called `NetComServer.comhost.dll`). If the shim is signed the shim will **not** attempt to discover the manifest on disk.
- * The manifest will contain a mapping from [`CLSID`](https://docs.microsoft.com/windows/desktop/com/com-class-objects-and-clsids) to managed assembly name and the [Fully-Qualified Name](https://docs.microsoft.com/dotnet/framework/reflection-and-codedom/specifying-fully-qualified-type-names) for the type. The format of this manifest is defined below. The shim's embedded mapping always takes precedence and in the case an embedded mapping is found, a `.clsidmap` file on disk will never be used.
+ * The manifest will contain a mapping from [`CLSID`](https://learn.microsoft.com/windows/desktop/com/com-class-objects-and-clsids) to managed assembly name and the [Fully-Qualified Name](https://learn.microsoft.com/dotnet/framework/reflection-and-codedom/specifying-fully-qualified-type-names) for the type. The format of this manifest is defined below. The shim's embedded mapping always takes precedence and in the case an embedded mapping is found, a `.clsidmap` file on disk will never be used.
* The manifest will define an exhaustive list of .NET classes the shim is permitted to provide.
* If a [`.runtimeconfig.json`](https://github.com/dotnet/cli/blob/master/Documentation/specs/runtime-configuration-file.md) file exists adjacent to the target managed assembly (`.runtimeconfig.json`), that file is used to describe the target framework and CLR configuration. The documentation for the `.runtimeconfig.json` format defines under what circumstances this file may be optional.
1) The `DllGetClassObject()` function verifies the `CLSID` mapping has a mapping for the `CLSID`.
@@ -71,7 +71,7 @@ When `DllGetClassObject()` is called in a COM activation scenario, the following
1) The shim attempts to load the latest version of the `hostfxr` library and retrieves the `hostfxr_initialize_for_runtime_config()` and `hostfxr_get_runtime_delegate()` exports.
1) The target assembly name is computed by stripping off the `.comhost.dll` prefix and replacing it with `.dll`. Using the name of the target assembly, the path to the `.runtimeconfig.json` file is then computed.
1) The `hostfxr_initialize_for_runtime_config()` export is called.
-1) Based on the `.runtimeconfig.json` the [framework](https://docs.microsoft.com/dotnet/core/packages#frameworks) to use can be determined and the appropriate `hostpolicy` library path is computed.
+1) Based on the `.runtimeconfig.json` the [framework](https://learn.microsoft.com/dotnet/core/packages#frameworks) to use can be determined and the appropriate `hostpolicy` library path is computed.
1) The `hostpolicy` library is loaded and various exports are retrieved.
* If a `hostpolicy` instance is already loaded, the one presently loaded is re-used.
* If a CLR is active within the process, the requested CLR version will be validated against that CLR. If version satisfiability fails, activation will fail.
@@ -104,17 +104,17 @@ When `DllGetClassObject()` is called in a COM activation scenario, the following
}
```
Note this API is not exposed outside of `System.Private.CoreLib` and is subject to change at any time.
- * The loading of the assembly will take place in a new [`AssemblyLoadContext`](https://docs.microsoft.com/dotnet/api/system.runtime.loader.assemblyloadcontext) for dependency isolation. Each assembly path will get a separate `AssemblyLoadContext`. This means that if an assembly provides multiple COM servers all of the servers from that assembly will reside in the same `AssemblyLoadContext`.
+ * The loading of the assembly will take place in a new [`AssemblyLoadContext`](https://learn.microsoft.com/dotnet/api/system.runtime.loader.assemblyloadcontext) for dependency isolation. Each assembly path will get a separate `AssemblyLoadContext`. This means that if an assembly provides multiple COM servers all of the servers from that assembly will reside in the same `AssemblyLoadContext`.
* The created `AssemblyLoadContext` will use an [`AssemblyDependencyResolver`](https://github.com/dotnet/runtime/issues/27787) that was supplied with the path to the assembly to load assemblies.
1) The `IClassFactory` instance is returned to the caller of `DllGetClassObject()` to attempt class activation.
The `DllCanUnloadNow()` function will always return `S_FALSE` indicating the shim is never able to be unloaded. This matches .NET Framework semantics but may be adjusted in the future if needed.
-The `DllRegisterServer()` and `DllUnregisterServer()` functions adhere to the [COM registration contract](https://docs.microsoft.com/windows/desktop/com/classes-and-servers) and enable registration and unregistration of the classes defined in the `CLSID` mapping manifest. Discovery of the mapping manifest is identical to that which occurs during a call to `DllGetClassObject()`.
+The `DllRegisterServer()` and `DllUnregisterServer()` functions adhere to the [COM registration contract](https://learn.microsoft.com/windows/desktop/com/classes-and-servers) and enable registration and unregistration of the classes defined in the `CLSID` mapping manifest. Discovery of the mapping manifest is identical to that which occurs during a call to `DllGetClassObject()`.
##### CLSID map format
-The `CLSID` mapping manifest is a JSON format (`.clsidmap` extension when on disk) that defines a mapping from `CLSID` to an assembly name and type name tuple as well as an optional [ProgID](https://docs.microsoft.com/windows/win32/com/-progid--key). Each `CLSID` mapping is a key in the outer JSON object.
+The `CLSID` mapping manifest is a JSON format (`.clsidmap` extension when on disk) that defines a mapping from `CLSID` to an assembly name and type name tuple as well as an optional [ProgID](https://learn.microsoft.com/windows/win32/com/-progid--key). Each `CLSID` mapping is a key in the outer JSON object.
``` json
{
@@ -129,9 +129,9 @@ The `CLSID` mapping manifest is a JSON format (`.clsidmap` extension when on dis
### .NET Core COM server creation
1) A new .NET Core class library project is created using [`dotnet.exe`][dotnet_link].
-1) A class is defined that has the [`GuidAttribute("")`][guid_link] and the [`ComVisibleAttribute(true)`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.comvisibleattribute).
+1) A class is defined that has the [`GuidAttribute("")`][guid_link] and the [`ComVisibleAttribute(true)`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.comvisibleattribute).
- In .NET Core, unlike .NET Framework, there is no generated class interface generation (i.e. `IClassX`). This means it is advantageous for users to have the class implement a marshalable interface.
- - A ProgID for the class can be defined using the [`ProgIdAttribute`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.progidattribute). If a ProgID is not explicitly specified, the namespace and class name will be used as the ProgID. This follows the same semantics as .NET Framework COM servers.
+ - A ProgID for the class can be defined using the [`ProgIdAttribute`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.progidattribute). If a ProgID is not explicitly specified, the namespace and class name will be used as the ProgID. This follows the same semantics as .NET Framework COM servers.
1) The `EnableComHosting` property is added to the project file.
- i.e. `true `
1) During class project build, the following actions occur if the `EnableComHosting` property is `true`:
@@ -147,11 +147,11 @@ Two options exist for registration and are a function of the intent of the class
#### Registry
-Class registration in the registry for .NET Core classes is greatly simplified and is now identical to that of a non-managed COM class. This is possible due to the presence of the aforementioned `.clsidmap` manifest. The application developer will be able to use the traditional [`regsvr32.exe`](https://docs.microsoft.com/windows-server/administration/windows-commands/regsvr32) tool for class registration.
+Class registration in the registry for .NET Core classes is greatly simplified and is now identical to that of a non-managed COM class. This is possible due to the presence of the aforementioned `.clsidmap` manifest. The application developer will be able to use the traditional [`regsvr32.exe`](https://learn.microsoft.com/windows-server/administration/windows-commands/regsvr32) tool for class registration.
#### Registration-Free
-[RegFree COM for .NET](https://docs.microsoft.com/dotnet/framework/interop/configure-net-framework-based-com-components-for-reg) is another style of registration, but does not require registry access. This approach is complicated by the use of [application manifests](https://docs.microsoft.com/windows/desktop/SbsCs/application-manifests), but does have benefits for limiting environment impact and simplifying deployment. A severe limitation of this approach is that in order to use RegFree COM with a .NET class, the Window OS assumes the use of `mscoree.dll` for the in-proc server. Without a change in the Windows OS, this assumption in the RegFree .NET scenario makes the existing manifest approach a broken scenario for .NET Core.
+[RegFree COM for .NET](https://learn.microsoft.com/dotnet/framework/interop/configure-net-framework-based-com-components-for-reg) is another style of registration, but does not require registry access. This approach is complicated by the use of [application manifests](https://learn.microsoft.com/windows/desktop/SbsCs/application-manifests), but does have benefits for limiting environment impact and simplifying deployment. A severe limitation of this approach is that in order to use RegFree COM with a .NET class, the Window OS assumes the use of `mscoree.dll` for the in-proc server. Without a change in the Windows OS, this assumption in the RegFree .NET scenario makes the existing manifest approach a broken scenario for .NET Core.
An example of a RegFree manifest for a .NET Framework class is below - note the absence of specifying a hosting server library (i.e. `mscoree.dll` is implied for the `clrClass` element).
@@ -196,7 +196,7 @@ The .NET Core steps for RegFree are as follows:
```
-1) The tool chain can optionally generate a [SxS](https://docs.microsoft.com/windows/desktop/sbscs/about-side-by-side-assemblies-) manifest for the shim. Both the SxS manifest _and_ the shim library will need to be app-local for the scenario to work. Note that the application developer is responsible for adding to or merging the generated shim's manifest with one the user may have defined for other scenarios. An example shim manifest is defined below and with it the SxS logic will naturally know to query the shim for the desired class. Note that multiple `comClass` tags can be added.
+1) The tool chain can optionally generate a [SxS](https://learn.microsoft.com/windows/desktop/sbscs/about-side-by-side-assemblies-) manifest for the shim. Both the SxS manifest _and_ the shim library will need to be app-local for the scenario to work. Note that the application developer is responsible for adding to or merging the generated shim's manifest with one the user may have defined for other scenarios. An example shim manifest is defined below and with it the SxS logic will naturally know to query the shim for the desired class. Note that multiple `comClass` tags can be added.
``` xml
@@ -231,10 +231,10 @@ The .NET Core steps for RegFree are as follows:
[Calling a .NET Component from a COM Component](https://msdn.microsoft.com/library/ms973802.aspx)
-[Using COM Types in Managed Code](https://docs.microsoft.com/previous-versions/dotnet/netframework-4.0/3y76b69k%28v%3dvs.100%29)
+[Using COM Types in Managed Code](https://learn.microsoft.com/previous-versions/dotnet/netframework-4.0/3y76b69k%28v%3dvs.100%29)
-[Exposing .NET Framework Components to COM](https://docs.microsoft.com/dotnet/framework/interop/exposing-dotnet-components-to-com)
+[Exposing .NET Framework Components to COM](https://learn.microsoft.com/dotnet/framework/interop/exposing-dotnet-components-to-com)
-[guid_link]: https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.guidattribute
-[dotnet_link]: https://docs.microsoft.com/dotnet/core/tools/dotnet
+[guid_link]: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.guidattribute
+[dotnet_link]: https://learn.microsoft.com/dotnet/core/tools/dotnet
diff --git a/docs/design/features/IJW-activation.md b/docs/design/features/IJW-activation.md
index d55032e46706a..3ae8e64c72ebe 100644
--- a/docs/design/features/IJW-activation.md
+++ b/docs/design/features/IJW-activation.md
@@ -44,7 +44,7 @@ Below are the entry-points that the Visual C++ team needs
When `_CorExeMain()` is called, the following will occur:
1) If a [`.runtimeconfig.json`](https://github.com/dotnet/cli/blob/master/Documentation/specs/runtime-configuration-file.md) file exists adjacent to the shim assembly (`.runtimeconfig.json`), that file will be used to describe CLR configuration details. The documentation for the `.runtimeconfig.json` format defines under what circumstances this file may be optional.
-2) Using the existing `hostfxr` library, attempt to discover the desired CLR and target [framework](https://docs.microsoft.com/en-us/dotnet/core/packages#frameworks).
+2) Using the existing `hostfxr` library, attempt to discover the desired CLR and target [framework](https://learn.microsoft.com/dotnet/core/packages#frameworks).
* If a CLR is active with the process, the requested CLR version will be validated against that CLR. If version satisfiability fails, activation will fail.
* If a CLR is **not** active with the process, an attempt will be made to create a satisfying CLR instance.
* Failure to create an instance will result in activation failure.
diff --git a/docs/design/features/byreflike-generics.md b/docs/design/features/byreflike-generics.md
index dec8c64a42db2..d529f18f140df 100644
--- a/docs/design/features/byreflike-generics.md
+++ b/docs/design/features/byreflike-generics.md
@@ -84,13 +84,13 @@ namespace System.Runtime.CompilerServices
Current examples of APIs that would need the attribute applied:
-- [`Span`](https://docs.microsoft.com/dotnet/api/system.span-1)
+- [`Span`](https://learn.microsoft.com/dotnet/api/system.span-1)
- `public Span(T[]? array);`
- `public Span(T[]? array, int start, int length);`
- `public T[] ToArray();`
- `public static implicit operator Span(ArraySegment segment);`
- `public static implicit operator Span(T[]? array);`
-- [`ReadOnlySpan`](https://docs.microsoft.com/dotnet/api/system.readonlyspan-1)
+- [`ReadOnlySpan`](https://learn.microsoft.com/dotnet/api/system.readonlyspan-1)
- `public ReadOnlySpan(T[]? array);`
- `public ReadOnlySpan(T[]? array, int start, int length);`
- `public T[] ToArray();`
diff --git a/docs/design/features/dllmap.md b/docs/design/features/dllmap.md
index b1c710e5bf7ee..e0e113e762e99 100644
--- a/docs/design/features/dllmap.md
+++ b/docs/design/features/dllmap.md
@@ -21,9 +21,9 @@ Mono also permits mapping of method names within libraries, but with the restric
.Net Core 3 provides a rich set of APIs to manage native libraries, as well as callbacks to influence native library resolution.
-- [NativeLibrary APIs](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.nativelibrary?view=netcore-3.0): Perform operations on native libraries (such as `Load()`, `Free()`, get the address of an exported symbol, etc.) in a platform-independent way from managed code.
-- [DllImport Resolver callback](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.nativelibrary.setdllimportresolver?view=netcore-3.0): Gets a callback for first-chance native library resolution using custom logic.
-- [Native Library Resolve event](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.loader.assemblyloadcontext.resolvingunmanageddll?view=netcore-3.0): Get an event for last-chance native library resolution using custom logic.
+- [NativeLibrary APIs](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.nativelibrary?view=netcore-3.0): Perform operations on native libraries (such as `Load()`, `Free()`, get the address of an exported symbol, etc.) in a platform-independent way from managed code.
+- [DllImport Resolver callback](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.nativelibrary.setdllimportresolver?view=netcore-3.0): Gets a callback for first-chance native library resolution using custom logic.
+- [Native Library Resolve event](https://learn.microsoft.com/dotnet/api/system.runtime.loader.assemblyloadcontext.resolvingunmanageddll?view=netcore-3.0): Get an event for last-chance native library resolution using custom logic.
These APIs can be used to implement custom native library resolution logic, including Mono-style DllMap.
diff --git a/docs/design/features/globalization-hybrid-mode.md b/docs/design/features/globalization-hybrid-mode.md
index 001ae20002cc9..2270fe897c1c0 100644
--- a/docs/design/features/globalization-hybrid-mode.md
+++ b/docs/design/features/globalization-hybrid-mode.md
@@ -270,8 +270,8 @@ Dependencies:
Web API does not expose locale-sensitive endsWith/startsWith function. As a workaround, both strings get normalized and weightless characters are removed. Resulting strings are cut to the same length and comparison is performed. This approach, beyond having the same compare option limitations as described under **String comparison**, has additional limitations connected with the workaround used. Because we are normalizing strings to be able to cut them, we cannot calculate the match length on the original strings. Methods that calculate this information throw PlatformNotSupported exception:
-- [CompareInfo.IsPrefix](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.compareinfo.isprefix?view=net-8.0#system-globalization-compareinfo-isprefix(system-readonlyspan((system-char))-system-readonlyspan((system-char))-system-globalization-compareoptions-system-int32@))
-- [CompareInfo.IsSuffix](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.compareinfo.issuffix?view=net-8.0#system-globalization-compareinfo-issuffix(system-readonlyspan((system-char))-system-readonlyspan((system-char))-system-globalization-compareoptions-system-int32@))
+- [CompareInfo.IsPrefix](https://learn.microsoft.com/dotnet/api/system.globalization.compareinfo.isprefix?view=net-8.0#system-globalization-compareinfo-isprefix(system-readonlyspan((system-char))-system-readonlyspan((system-char))-system-globalization-compareoptions-system-int32@))
+- [CompareInfo.IsSuffix](https://learn.microsoft.com/dotnet/api/system.globalization.compareinfo.issuffix?view=net-8.0#system-globalization-compareinfo-issuffix(system-readonlyspan((system-char))-system-readonlyspan((system-char))-system-globalization-compareoptions-system-int32@))
- `IgnoreSymbols`
Only comparisons that do not skip character types are allowed. E.g. `IgnoreSymbols` skips symbol-chars in comparison/indexing. All `CompareOptions` combinations that include `IgnoreSymbols` throw `PlatformNotSupportedException`.
diff --git a/docs/design/features/globalization-invariant-mode.md b/docs/design/features/globalization-invariant-mode.md
index 62544139522dd..0b71ffc992d38 100644
--- a/docs/design/features/globalization-invariant-mode.md
+++ b/docs/design/features/globalization-invariant-mode.md
@@ -2,7 +2,7 @@
Author: [Tarek Mahmoud Sayed](https://github.com/tarekgh)
-The globalization invariant mode - new in .NET Core 2.0 - enables you to remove application dependencies on globalization data and [globalization behavior](https://docs.microsoft.com/en-us/dotnet/standard/globalization-localization/). This mode is an opt-in feature that provides more flexibility if you care more about reducing dependencies and the size of distribution than globalization functionality or globalization-correctness.
+The globalization invariant mode - new in .NET Core 2.0 - enables you to remove application dependencies on globalization data and [globalization behavior](https://learn.microsoft.com/dotnet/standard/globalization-localization/). This mode is an opt-in feature that provides more flexibility if you care more about reducing dependencies and the size of distribution than globalization functionality or globalization-correctness.
The drawback of running in the invariant mode is applications will get poor globalization support. This new option is only recommended for developers that understand globalization and the impact of its absence.
@@ -54,9 +54,9 @@ Turkish I casing will not be supported when using Turkish cultures.
## String sorting and searching
-String operations like [Compare](https://docs.microsoft.com/dotnet/api/?term=string.compare), [IndexOf](https://docs.microsoft.com/dotnet/api/?term=string.indexof) and [LastIndexOf](https://docs.microsoft.com/dotnet/api/?term=string.lastindexof) are always performed as [ordinal](https://en.wikipedia.org/wiki/Ordinal_number) and not linguistic operations regardless of the string comparing options passed to the APIs.
+String operations like [Compare](https://learn.microsoft.com/dotnet/api/?term=string.compare), [IndexOf](https://learn.microsoft.com/dotnet/api/?term=string.indexof) and [LastIndexOf](https://learn.microsoft.com/dotnet/api/?term=string.lastindexof) are always performed as [ordinal](https://en.wikipedia.org/wiki/Ordinal_number) and not linguistic operations regardless of the string comparing options passed to the APIs.
-The [ignore case](https://docs.microsoft.com/dotnet/api/system.globalization.compareoptions.ignorecase) string sorting option is supported but only for the ASCII range as mentioned previously.
+The [ignore case](https://learn.microsoft.com/dotnet/api/system.globalization.compareoptions.ignorecase) string sorting option is supported but only for the ASCII range as mentioned previously.
For example, the following comparison will resolve to being unequal:
@@ -71,7 +71,7 @@ However, the following comparison will resolve to being equal:
* 'I', using
* CompareOptions.Ignorecase
-It is worth noticing that all other [sort comparison options](https://docs.microsoft.com/dotnet/api/system.globalization.compareoptions) (for example, ignore symbols, ignore space, Katakana, Hiragana) will have no effect in the invariant mode (they are ignored).
+It is worth noticing that all other [sort comparison options](https://learn.microsoft.com/dotnet/api/system.globalization.compareoptions) (for example, ignore symbols, ignore space, Katakana, Hiragana) will have no effect in the invariant mode (they are ignored).
## Sort keys
diff --git a/docs/design/features/hosting-layer-apis.md b/docs/design/features/hosting-layer-apis.md
index 37d26972ae79a..0eab1666429bb 100644
--- a/docs/design/features/hosting-layer-apis.md
+++ b/docs/design/features/hosting-layer-apis.md
@@ -4,7 +4,7 @@ Functionality for advanced hosting scenarios is exposed on the `hostfxr` and `ho
The `char_t` strings in the below API descriptions are defined based on the platform:
* Windows - UTF-16 (2-byte `wchar_t`)
- * Note that `wchar_t` is defined as a [native type](https://docs.microsoft.com/cpp/build/reference/zc-wchar-t-wchar-t-is-native-type), which is the default in Visual Studio.
+ * Note that `wchar_t` is defined as a [native type](https://learn.microsoft.com/cpp/build/reference/zc-wchar-t-wchar-t-is-native-type), which is the default in Visual Studio.
* Unix - UTF-8 (1-byte `char`)
## Host FXR
diff --git a/docs/design/features/localization-options.md b/docs/design/features/localization-options.md
index 6b76f525a4782..f23fbdcfb9062 100644
--- a/docs/design/features/localization-options.md
+++ b/docs/design/features/localization-options.md
@@ -15,9 +15,9 @@ The goal is to support:
### Windows
-On Windows, [resource script (.rc) files](https://docs.microsoft.com/cpp/windows/resource-files-visual-studio) are used to create resources that will be embedded into a binary. These files define [`STRINGTABLE`](https://docs.microsoft.com/windows/win32/menurc/stringtable-resource) resources containing the resource strings. Each string has a resource identifier - a symbol name mapped to an integer value - which can be used to look up the string value.
+On Windows, [resource script (.rc) files](https://learn.microsoft.com/cpp/windows/resource-files-visual-studio) are used to create resources that will be embedded into a binary. These files define [`STRINGTABLE`](https://learn.microsoft.com/windows/win32/menurc/stringtable-resource) resources containing the resource strings. Each string has a resource identifier - a symbol name mapped to an integer value - which can be used to look up the string value.
-The [`LoadString`](https://docs.microsoft.com/windows/win32/api/winuser/nf-winuser-loadstringw) and [`FormatMessage`](https://docs.microsoft.com/windows/win32/api/winbase/nf-winbase-formatmessage) APIs retrieve a string resources based on a specified identifier (the integer value of the resource identifier) from a specified module. These APIs leave it to their consumer to find and load the appropriate module containing the desired resources. While resources for all languages can be included in the main binary itself, it is common to separate language-specific resources into resource-only libraries.
+The [`LoadString`](https://learn.microsoft.com/windows/win32/api/winuser/nf-winuser-loadstringw) and [`FormatMessage`](https://learn.microsoft.com/windows/win32/api/winbase/nf-winbase-formatmessage) APIs retrieve a string resources based on a specified identifier (the integer value of the resource identifier) from a specified module. These APIs leave it to their consumer to find and load the appropriate module containing the desired resources. While resources for all languages can be included in the main binary itself, it is common to separate language-specific resources into resource-only libraries.
### Linux
@@ -284,7 +284,7 @@ Any automated testing would likely also require some form of language override.
### Single-file
-The standard way of doing native localization is based on having separate resources files. On Windows, it is possible to embed resources for multiple languages into one library and use [`FormatMessage`](https://docs.microsoft.com/windows/win32/api/winbase/nf-winbase-formatmessage) or a combination of [`FindResourceEx`](https://docs.microsoft.com/windows/win32/api/winbase/nf-winbase-findresourceexa) and [`LoadResource`](https://docs.microsoft.com/windows/win32/api/libloaderapi/nf-libloaderapi-loadresource) to load the resource for a specific language. On Linux and OSX, no such platform support exists.
+The standard way of doing native localization is based on having separate resources files. On Windows, it is possible to embed resources for multiple languages into one library and use [`FormatMessage`](https://learn.microsoft.com/windows/win32/api/winbase/nf-winbase-formatmessage) or a combination of [`FindResourceEx`](https://learn.microsoft.com/windows/win32/api/winbase/nf-winbase-findresourceexa) and [`LoadResource`](https://learn.microsoft.com/windows/win32/api/libloaderapi/nf-libloaderapi-loadresource) to load the resource for a specific language. On Linux and OSX, no such platform support exists.
Extracting files to disk has proven to be extremely problematic across all platforms (permissions, anti-virus, clean up). Adding native resources to that extraction would only exacerbate the existing issues. This means that localized resources would need be read from memory. A custom solution would need to be created and maintained:
- Format for storing identifiers and their corresponding strings for every language
diff --git a/docs/design/features/sharedfx-lookup.md b/docs/design/features/sharedfx-lookup.md
index 870bee16cdd43..7f5532e45c9c7 100644
--- a/docs/design/features/sharedfx-lookup.md
+++ b/docs/design/features/sharedfx-lookup.md
@@ -4,7 +4,7 @@
There are two main ways of running .NET Applications: through `dotnet` or through the `apphost` executables. The executable is in charge of finding and loading `hostfxr`. `hostfxr`, in turn, must find and load `hostpolicy`. It is also responsible for searching for the SDK when running .NET SDK commands. Finally, `hostpolicy` must find and load the runtime (`coreclr`). See [host components](host-components.md) for details.
-An application can either be [framework-dependent](https://docs.microsoft.com/dotnet/core/deploying/#publish-framework-dependent) or [self-contained](https://docs.microsoft.com/dotnet/core/deploying/#publish-self-contained). Framework-dependent apps must have the runtime files inside predefined folders. Self-contained apps are expected to have their dependencies in the same location as the executable.
+An application can either be [framework-dependent](https://learn.microsoft.com/dotnet/core/deploying/#publish-framework-dependent) or [self-contained](https://learn.microsoft.com/dotnet/core/deploying/#publish-self-contained). Framework-dependent apps must have the runtime files inside predefined folders. Self-contained apps are expected to have their dependencies in the same location as the executable.
## Semantic Versioning
@@ -42,7 +42,7 @@ There are two possibilities for a muxer: it can be a framework-dependent app or
In the first case the app file path should have been specified as an argument to the dotnet.exe.
In the second case the `dotnet.dll` from SDK must be invoked as a framework-dependent app. At first the running program searches for the `global.json` file which may have specified a CLI version. It starts from the current working directory and looks for it inside all parent folder hierarchy. After that, it searches for the dotnet.dll file inside the `sdk\` sub-folder in the executable directory.
-The exact algorithm how versions as matched is described (with some history) in the [docs](https://docs.microsoft.com/en-us/dotnet/core/tools/global-json#matching-rules)
+The exact algorithm how versions as matched is described (with some history) in the [docs](https://learn.microsoft.com/dotnet/core/tools/global-json#matching-rules)
Note: if the SDK lookup is invoked through `hostfxr_resolve_sdk2` the algorithm is the same, expect that the function can disallow pre-release versions via the `hostfxr_resolve_sdk2_flags_t::disallow_prerelease` flag.
diff --git a/docs/design/features/source-generator-pinvokes.md b/docs/design/features/source-generator-pinvokes.md
index d13581b9353ff..f9d1a3b9039f4 100644
--- a/docs/design/features/source-generator-pinvokes.md
+++ b/docs/design/features/source-generator-pinvokes.md
@@ -2,7 +2,7 @@
## Purpose
-The CLR possesses a rich built-in marshaling mechanism for interoperability with native code that is handled at runtime. This system was designed to free .NET developers from having to author complex and potentially ABI sensitive [type conversion code][typemarshal_link] from a managed to an unmanaged environment. The built-in system works with both [P/Invoke][pinvoke_link] (i.e. `DllImportAttribute`) and [COM interop](https://docs.microsoft.com/dotnet/standard/native-interop/cominterop). The generated portion is typically called an ["IL Stub"][il_stub_link] since the stub is generated by inserting IL instructions into a stream and then passing that stream to the JIT for compilation.
+The CLR possesses a rich built-in marshaling mechanism for interoperability with native code that is handled at runtime. This system was designed to free .NET developers from having to author complex and potentially ABI sensitive [type conversion code][typemarshal_link] from a managed to an unmanaged environment. The built-in system works with both [P/Invoke][pinvoke_link] (i.e. `DllImportAttribute`) and [COM interop](https://learn.microsoft.com/dotnet/standard/native-interop/cominterop). The generated portion is typically called an ["IL Stub"][il_stub_link] since the stub is generated by inserting IL instructions into a stream and then passing that stream to the JIT for compilation.
A consequence of this approach is that marshaling code is not immediately available post-link for AOT scenarios (e.g. [`crossgen`](../../workflow/building/coreclr/crossgen.md) and [`crossgen2`](crossgen2-compilation-structure-enhancements.md)). The immediate unavailability of this code has been mitigated by a complex mechanism to have marshalling code generated by during AOT compilation. The [IL Linker][ilinker_link] is another tool that struggles with runtime generated code since it is unable to understand all potential used types without seeing what is generated.
@@ -10,7 +10,7 @@ The user experience of the built-in generation initially appears ideal, but ther
* Bug fixes in the marshaling system require an update to the entire runtime.
* New types require enhancements to the marshaling system for efficient marshal behavior.
- * [`ICustomMarshaler`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.icustommarshaler) incurs a substantial performance penalty.
+ * [`ICustomMarshaler`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.icustommarshaler) incurs a substantial performance penalty.
* Once a marshaling bug becomes expected behavior the bug is difficult to fix. This is due to user reliance on shipped behavior and since the marshaling system is built into the runtime there aren't ways to select previous or new behavior.
* Example involving COM marshaling: https://github.com/dotnet/coreclr/pull/23974.
* Debugging the auto-generated marshaling IL Stub is difficult for runtime developers and close to impossible for consumers of P/Invokes.
@@ -26,7 +26,7 @@ The [Roslyn Compiler](https://github.com/dotnet/roslyn) team is working on a [So
* [Source Generators][source_gen_link]
* Branch: https://github.com/dotnet/roslyn/tree/features/source-generators
-* Support for non-`void` return types in [`partial`](https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/partial-method) methods.
+* Support for non-`void` return types in [`partial`](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/partial-method) methods.
* https://github.com/dotnet/csharplang/issues/3301
## Design
@@ -61,11 +61,11 @@ At (A) in the above code snippet, the runtime is told to look for an export name
2) The runtime attempts to find a binary with the name supplied in `DllImportAttribute`.
- * Discovery of the target binary is complicated and can be influenced by the [`AssemblyLoadContext`](https://docs.microsoft.com/dotnet/api/system.runtime.loader.assemblyloadcontext) and [`NativeLibrary`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.nativelibrary) classes.
+ * Discovery of the target binary is complicated and can be influenced by the [`AssemblyLoadContext`](https://learn.microsoft.com/dotnet/api/system.runtime.loader.assemblyloadcontext) and [`NativeLibrary`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.nativelibrary) classes.
-3) Once the binary is found and loaded into the runtime, it is queried for the expected export name. The name of the attributed function is used by default but this is configurable by the [`DllImportAttribute.EntryPoint`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.entrypoint) property.
+3) Once the binary is found and loaded into the runtime, it is queried for the expected export name. The name of the attributed function is used by default but this is configurable by the [`DllImportAttribute.EntryPoint`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.entrypoint) property.
- * This process is also influenced by additional `DllImportAttribute` properties as well as by the underlying platform. For example, the [Win32 API ANSI/UNICODE convention](https://docs.microsoft.com/windows/win32/intl/conventions-for-function-prototypes) on Windows is respected and a(n) `A`/`W` suffix may be appended to the function name if it is not immediately found.
+ * This process is also influenced by additional `DllImportAttribute` properties as well as by the underlying platform. For example, the [Win32 API ANSI/UNICODE convention](https://learn.microsoft.com/windows/win32/intl/conventions-for-function-prototypes) on Windows is respected and a(n) `A`/`W` suffix may be appended to the function name if it is not immediately found.
4) The IL Stub is called like any other .NET method.
@@ -111,7 +111,7 @@ During the source generation process the metadata in the `LibraryImportAttribute
The Source Generator would generate the implementation of the partial method (D) in a separate translation unit (`Stubs.g.cs`). At point (E) a `DllImportAttribute` declaration is created based on the user's original declaration (A) for a private P/Invoke specifically for the generated code. The P/Invoke signature from the original declaration would be modified to contain only [blittable types][blittable_link] to ensure the JIT could inline the invocation. Finally note that the user's original function signature would remain in to avoid impacting existing callsites.
-In this system it is not defined how marshaling of specific types would be performed. The built-in runtime has complex rules for some types, and it is these rules that once shipped become the de facto standard - often times regardless if the behavior is a bug or not. The design here is not concerned with how the arguments go from a managed to unmanaged environment. With the IL Stub generation extracted from the runtime new type marshaling (e.g. [`Span`](https://docs.microsoft.com/dotnet/api/system.span-1)) could be introduced without requiring an corresponding update to the runtime itself. The `Span` type is good example of a type that at present has no support for marshaling, but with this proposal users could update to the latest generator and have support without changing the runtime.
+In this system it is not defined how marshaling of specific types would be performed. The built-in runtime has complex rules for some types, and it is these rules that once shipped become the de facto standard - often times regardless if the behavior is a bug or not. The design here is not concerned with how the arguments go from a managed to unmanaged environment. With the IL Stub generation extracted from the runtime new type marshaling (e.g. [`Span`](https://learn.microsoft.com/dotnet/api/system.span-1)) could be introduced without requiring an corresponding update to the runtime itself. The `Span` type is good example of a type that at present has no support for marshaling, but with this proposal users could update to the latest generator and have support without changing the runtime.
### Adoption of Source Generator
@@ -199,11 +199,11 @@ namespace System.Runtime.InteropServices
* How will users get error messages during source generator?
- * The Source Generator API will be permitted to provide warnings and errors through the [Roslyn SDK](https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/).
+ * The Source Generator API will be permitted to provide warnings and errors through the [Roslyn SDK](https://learn.microsoft.com/dotnet/csharp/roslyn-sdk/).
* Will it be possible to completely replicate the marshaling rules in the current built-in system using existing .NET APIs?
- * No. There are rules and semantics that would be difficult to replicate with the current .NET API surface. Additional .NET APIs will likely need to be added in order to allow a Source Generator implementation to provide identical semantics with the built-in system (e.g. Respecting the semantics of [`DllImportAttribute.SetLastError`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.setlasterror)).
+ * No. There are rules and semantics that would be difficult to replicate with the current .NET API surface. Additional .NET APIs will likely need to be added in order to allow a Source Generator implementation to provide identical semantics with the built-in system (e.g. Respecting the semantics of [`DllImportAttribute.SetLastError`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.setlasterror)).
## References
@@ -214,10 +214,10 @@ namespace System.Runtime.InteropServices
[IL Stubs description][il_stub_link]
-[typemarshal_link]: https://docs.microsoft.com/dotnet/standard/native-interop/type-marshaling
-[pinvoke_link]: https://docs.microsoft.com/dotnet/standard/native-interop/pinvoke
+[typemarshal_link]: https://learn.microsoft.com/dotnet/standard/native-interop/type-marshaling
+[pinvoke_link]: https://learn.microsoft.com/dotnet/standard/native-interop/pinvoke
[comwrappers_link]: https://github.com/dotnet/runtime/issues/1845
[il_stub_link]: https://mattwarren.org/2019/09/26/Stubs-in-the-.NET-Runtime/
[source_gen_link]: https://github.com/dotnet/roslyn/blob/features/source-generators/docs/features/source-generators.md
-[blittable_link]: https://docs.microsoft.com/dotnet/framework/interop/blittable-and-non-blittable-types
+[blittable_link]: https://learn.microsoft.com/dotnet/framework/interop/blittable-and-non-blittable-types
[il_linker_link]: https://github.com/dotnet/runtime/tree/main/src/tools/illink
diff --git a/docs/design/features/standalone-gc-loading.md b/docs/design/features/standalone-gc-loading.md
index 3c0b0e79be248..606b033ceb386 100644
--- a/docs/design/features/standalone-gc-loading.md
+++ b/docs/design/features/standalone-gc-loading.md
@@ -5,6 +5,10 @@ Author: Sean Gillespie (@swgillespie) - 2017
This document aims to provide a specification for how a standalone GC is
to be loaded and what is to happen in the case of version mismatches.
+**[Update June 2024] Warning** - The behavior described in this spec for how the CLR interprets environment variables
+is out-of-date. See the [public documentation](https://learn.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector#standalone-gc)
+if you want up-to-date instructions on how to configure standalone GC.
+
## Definitions
Before diving in to the specification, it's useful to precisely define
diff --git a/docs/design/features/unloadability.md b/docs/design/features/unloadability.md
index 7ca316e0887b5..bc2e20b458d5e 100644
--- a/docs/design/features/unloadability.md
+++ b/docs/design/features/unloadability.md
@@ -29,7 +29,7 @@ ASP.NET (not Core) originally used AppDomains to support dynamic compiling and r
ASP.NET Core moved to a more static model because of the lack of ability to unload stuff. Many of their customers did the same thing too. So, there is no pressing need for unloadability there at the moment.
However, they use two tool that could potentially benefit from the unloadability
-* Dotnet watch tool that watches a directory with sources and when a source file changes, it triggers recompilation and re-deployment. So, people can edit a source code used for their web page and the web server gets automatically recompiled and restarted. A need to restart the process negatively affects its performance. So, the ability to unload and reload just the modified assemblies without process restart would be very helpful here. See https://docs.microsoft.com/en-us/aspnet/core/tutorials/dotnet-watch?view=aspnetcore-2.1 for more details on the watch tool usage in ASP.NET Core.
+* Dotnet watch tool that watches a directory with sources and when a source file changes, it triggers recompilation and re-deployment. So, people can edit a source code used for their web page and the web server gets automatically recompiled and restarted. A need to restart the process negatively affects its performance. So, the ability to unload and reload just the modified assemblies without process restart would be very helpful here. See https://learn.microsoft.com/aspnet/core/tutorials/dotnet-watch?view=aspnetcore-2.1 for more details on the watch tool usage in ASP.NET Core.
* Compilation server for Razor pages (on demand .cshtml files compilation to .dll). (https://github.com/aspnet/Razor/blob/master/src/Microsoft.AspNetCore.Razor.Tools/CompilerHost.cs)
### LINQPad
LINQPad (https://www.linqpad.net) is a very popular third-party tool for designing LINQ queries against various data sources. It uses AppDomains and their unloading mechanism heavily for the following purposes:
diff --git a/docs/design/features/y2038.md b/docs/design/features/y2038.md
new file mode 100644
index 0000000000000..3ce613ab893ee
--- /dev/null
+++ b/docs/design/features/y2038.md
@@ -0,0 +1,91 @@
+# Y2038 support in .NET 9 Linux arm32
+
+In .NET 9, we addressed the Y2038 problem for Linux arm32. @mattheweshleman [noticed](https://github.com/dotnet/runtime/issues/96460) the issue early in the release cycle, and we also [hit](https://github.com/dotnet/runtime/issues/101444) this when our Linux arm32 builds started hitting OpenSSL-related errors on Ubuntu 24.04, the first Ubuntu version to [enable 64-bit `time_t` by default for Linux arm32](https://discourse.ubuntu.com/t/ubuntu-24-04-lts-noble-numbat-release-notes/39890#year-2038-support-for-the-armhf-architecture-5). This document describes our approach to Y2038 support.
+
+### Summary
+
+Our default posture for new .NET versions is to align with the latest Linux distribution first, and then work backwards to determine a reasonable compatibility story for older distributions. The .NET 9 Linux arm32 build requires glibc 2.35 and uses 64-bit `time_t` by default. We've made this change to align with Ubuntu 24.04. This change works on systems with 32-bit `time_t` but cannot represent times larger than 32 bits. We detect whether OpenSSL uses 32-bit `time_t` and fail predictably if the time being represented on the .NET side does not fit in 32 bits.
+
+### Y2038 in Linux
+
+Y2038 support at the [kernel](https://lwn.net/Articles/643234/) layer includes new versions of syscalls that use 64-bit versions of time_t. Userspace programs that use 32-bit time_t continue to work with this kernel.
+
+The next layer up is [glibc](https://sourceware.org/glibc/wiki/Y2038ProofnessDesign), which got Y2038 support in version 2.34. Like the kernel, glibc took a backwards-compatible approach. For every existing API symbol that used 32-bit time, glibc added a new 64-bit equivalent. The glibc headers provide a define `__TIME_BITS` that determines which versions of the time-related symbols are referenced at compile-time. For example, a call to glibc's `mktime` becomes a call to `__mktime64` when built with `__TIME_BITS==64`.
+
+However, the backwards compatibility ends with glibc. Linux distributions took on the project of building the remaining distribution-provided userspace libraries and applications with `__TIME_BITS=64`, introducing an ABI break at the boundary of any library with public surface that referenced `time_t`.
+
+Normally, ABI breeaks like this are not a problem for the Linux ecosystem because distributions rebuild all packages using the new ABI. However, the Microsoft distribution of .NET is somewhat unique in that it provides one set of binaries that are compatible with a broad range of distros (as long as the architecture and libc flavor match). This is similar to Python's [manylinux](https://github.com/pypa/manylinux) wheels.
+
+[Ubuntu](https://discourse.ubuntu.com/t/ubuntu-24-04-lts-noble-numbat-release-notes/39890#year-2038-support-for-the-armhf-architecture-5) made this change in 24.04, and [Debian](https://wiki.debian.org/ReleaseGoals/64bit-time) 13 is planned to be the first Debian release with 64-bit time.
+
+[musl](https://musl.libc.org/time64.html) version 1.2.0 got 64-bit time_t support, which was adopted in [Alpine](https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.13.0) 3.13.
+
+### .NET builds
+
+.NET official builds are produced by building the product on a [dedicated set of build images](https://github.com/dotnet/runtime/blob/main/docs/workflow/building/coreclr/linux-instructions.md). The images run Azure Linux 3.0 with an up-to-date cross-compilation toolchain, and also include a root filesystem of an old Linux distribution that provides an old version of glibc (or musl libc), which determines the libc compatibility of our builds.
+
+In .NET 8, we [support](https://github.com/dotnet/core/blob/main/release-notes/8.0/supported-os.md#libc-compatibility) glibc 2.23 and musl 1.2.2, by building the product with a root filesystem from Ubuntu 16.04 and Alpine 3.13, respectively.
+
+### .NET Y2038 support
+
+.NET 8 already [supports](https://github.com/dotnet/runtime/pull/51099) 64-bit time on musl Linux, and on architectures other than 32-bit arm. This just leaves the glibc-based arm32 Linux build.
+
+#### glibc
+
+Because our build already [defined](https://github.com/dotnet/runtime/pull/100461) `_TIME_BITS=64`, the main change we had to make was to [update](https://github.com/dotnet/dotnet-buildtools-prereqs-docker/pull/1037) the Ubuntu version of our rootfs to one that had a glibc with `_TIME_BITS` support. By targeting Ubuntu 22.04, .NET would be built with 64-bit `time_t`, allowing `DateTime.UtcNow` to [work](https://github.com/dotnet/runtime/issues/96460) correctly past Y2038.
+
+With this change, glibc-based .NET 9 (on Linux arm) is only [supported](https://github.com/dotnet/core/blob/main/release-notes/9.0/supported-os.md) on distributions with at least glibc 2.35 (from Ubuntu 22.04).
+
+#### OpenSSL
+
+Notice that we require a 64-bit time compatible glibc, _but_ the rest of the userspace may still be built with 32-bit time. This causes further problems when .NET interacts with other userspace libraries, in particular OpenSSL. An initial analysis [identified](https://github.com/dotnet/runtime/issues/101444) a couple of spots where .NET was passing `time_t` values (now 64-bit, with the aforementioned change) into OpenSSL functions. Before Ubuntu 24.04 and Debian 13, this meant we would be passing 64-bit values into functions that expected 32-bit values at two [callsites](https://github.com/dotnet/runtime/issues/101444#issuecomment-2077632497):
+
+- One was passing a time to OpenSSL's `X509_VERIFY_PARAM_set_time` for the purpose of validating a certificate chain.
+- Another was calling `X509_cmp_time` to compare the current time with a time returned from an OCSP response, as part of getting the expiry time.
+
+We didn't want to cause a potential security hole by clamping a larger-than-32-bit time to `INT_MAX` or `INT_MIN`, as that might (for example) cause OpenSSL to accept a certificate chain valid during the Y2038 rollover, well past Y2038 (as it would internally be comparing an `ASN1_GENERALIZEDTIME` that does not have the Y2038 problem with a 32-bit time).
+
+Instead we wanted to detect whether we were running with an OpenSSL that used 32-bit `time_t`, and fail predictably if working with times that did not fit in 32 bits.
+
+We solved this by calling a simple OpenSSL function, `OPENSSL_gmtime`, that takes a pointer to a `time_t` and returns a broken-down time in the form of a `tm` struct. For this call we use an ABI trick: we pass in a 64-bit `time_t` as a pointer, and 32-bit `time_t` builds of OpenSSL will interpret the low 32 bits of the referenced value as a 32-bit `time_t` due to little-endianness. We then examine the broken-down time to see whether it represents the full 64-bit value (indicating that OpenSSL is using 64-bit `time_t`), or just the lower 32 bits.
+
+[Here](https://github.com/dotnet/runtime/pull/102410/files#diff-592e31e5115ea6d3235bc9a81ee765635da398589f1bd51d7d66bfbca814f1b6R236-R251S) is the interesting bit of code:
+
+```c
+ // This value will represent a time in year 2038 if 64-bit time is used,
+ // or 1901 if the lower 32 bits are interpreted as a 32-bit time_t value.
+ time_t timeVal = (time_t)INT_MAX + 1;
+ struct tm tmVal = { 0 };
+
+ // Detect whether openssl is using 32-bit or 64-bit time_t.
+ // If it uses 32-bit time_t, little-endianness means that the pointer
+ // will be interpreted as a pointer to the lower 32 bits of timeVal.
+ // tm_year is the number of years since 1900.
+ if (!OPENSSL_gmtime(&timeVal, &tmVal) || (tmVal.tm_year != 138 && tmVal.tm_year != 1))
+ {
+ fprintf(stderr, "Cannot determine the time_t size used by libssl\n");
+ abort();
+ }
+
+ g_libSslUses32BitTime = (tmVal.tm_year == 1);
+```
+
+Then at the other callsites, we just check if our value is larger than 32 bits, and fail early if it is, or do the right thing for the 32-bit version of OpenSSL if not, by calling versions of the OpenSSL functions that take 32-bit `time_t`. For [example](https://github.com/dotnet/runtime/pull/102410/files#diff-b144366bd4c3520d0793a1b06c10c5efb57f85f6bb68a1a9073f8dd0f1a0efa5R968-R976):
+
+```c
+ if (g_libSslUses32BitTime)
+ {
+ if (verifyTime > INT_MAX || verifyTime < INT_MIN)
+ {
+ return 0;
+ }
+
+ // Cast to a signature that takes a 32-bit value for the time.
+ ((void (*)(X509_VERIFY_PARAM*, int32_t))(void*)(X509_VERIFY_PARAM_set_time))(verifyParams, (int32_t)verifyTime);
+ return 1;
+ }
+```
+
+This cast is ensuring that the call uses the correct ABI that the OpenSSL expects for the 32-bit `time_t` value.
+
+With that, we support running on 64-bit `time_t` compatible glibc, along with either 32-bit or 64-bit `time_t` OpenSSL, at least until we hit a time that does not fit into 32 bits.
diff --git a/docs/design/libraries/LibraryImportGenerator/Compatibility.md b/docs/design/libraries/LibraryImportGenerator/Compatibility.md
index 92f0c8e85e6a5..5105b6cc42ef7 100644
--- a/docs/design/libraries/LibraryImportGenerator/Compatibility.md
+++ b/docs/design/libraries/LibraryImportGenerator/Compatibility.md
@@ -51,15 +51,15 @@ In the event a marshaller would generate code that has a specific target framewo
### Semantic changes compared to `DllImportAttribute`
-[`CharSet`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.charset) has been replaced with a new `StringMarshalling` enumeration. `Ansi` and `Auto` are no longer supported as first-class options and `Utf8` has been added.
+[`CharSet`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.charset) has been replaced with a new `StringMarshalling` enumeration. `Ansi` and `Auto` are no longer supported as first-class options and `Utf8` has been added.
-With `DllImportAttribute`, the default value of [`CharSet`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.charset) is runtime/language-defined. In the built-in system, the default value of the `CharSet` property is `CharSet.Ansi`. The P/Invoke source generator makes no assumptions about `StringMarshalling` if it is not explicitly set on `LibraryImportAttribute`. Marshalling of `char` or `string` requires explicitly specifying marshalling information.
+With `DllImportAttribute`, the default value of [`CharSet`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.charset) is runtime/language-defined. In the built-in system, the default value of the `CharSet` property is `CharSet.Ansi`. The P/Invoke source generator makes no assumptions about `StringMarshalling` if it is not explicitly set on `LibraryImportAttribute`. Marshalling of `char` or `string` requires explicitly specifying marshalling information.
-[`BestFitMapping`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.bestfitmapping) and [`ThrowOnUnmappableChar`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.throwonunmappablechar) will not be supported for `LibraryImportAttribute`. These values only have meaning on Windows when marshalling string data (`char`, `string`, `StringBuilder`) as [ANSI](https://docs.microsoft.com/windows/win32/intl/code-pages). As the general recommendation - including from Windows - is to move away from ANSI, the P/Invoke source generator will not support these fields.
+[`BestFitMapping`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.bestfitmapping) and [`ThrowOnUnmappableChar`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.throwonunmappablechar) will not be supported for `LibraryImportAttribute`. These values only have meaning on Windows when marshalling string data (`char`, `string`, `StringBuilder`) as [ANSI](https://learn.microsoft.com/windows/win32/intl/code-pages). As the general recommendation - including from Windows - is to move away from ANSI, the P/Invoke source generator will not support these fields.
-[`CallingConvention`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.callingconvention) will not be supported for `LibraryImportAttribute`. Users will be required to use the new `UnmanagedCallConvAttribute` attribute instead. This attribute provides support for extensible calling conventions and provides parity with the `UnmanagedCallersOnlyAttribute` attribute and C# function pointer syntax. We will enable our conversion code-fix to automatically convert explicit and known calling convention usage to use the `UnmanagedCallConvAttribute`.
+[`CallingConvention`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.callingconvention) will not be supported for `LibraryImportAttribute`. Users will be required to use the new `UnmanagedCallConvAttribute` attribute instead. This attribute provides support for extensible calling conventions and provides parity with the `UnmanagedCallersOnlyAttribute` attribute and C# function pointer syntax. We will enable our conversion code-fix to automatically convert explicit and known calling convention usage to use the `UnmanagedCallConvAttribute`.
-[`ExactSpelling`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.exactspelling) will not be supported for `LibraryImportAttribute`. If `ExactSpelling` is used on an existing `DllImport`, the offered code-fix will provide users with additional options for using `A` or `W` suffixed variants depending on the provided `CharSet` so they can explicitly choose which spelling is correct for their scenario.
+[`ExactSpelling`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.exactspelling) will not be supported for `LibraryImportAttribute`. If `ExactSpelling` is used on an existing `DllImport`, the offered code-fix will provide users with additional options for using `A` or `W` suffixed variants depending on the provided `CharSet` so they can explicitly choose which spelling is correct for their scenario.
### Required references
@@ -68,30 +68,30 @@ The following framework references are required:
- `System.Runtime`
- `System.Runtime.InteropServices`
-These are all part of `NetCoreApp` and will be referenced by default unless [implicit framework references are disabled](https://docs.microsoft.com/dotnet/core/project-sdk/msbuild-props#disableimplicitframeworkreferences).
+These are all part of `NetCoreApp` and will be referenced by default unless [implicit framework references are disabled](https://learn.microsoft.com/dotnet/core/project-sdk/msbuild-props#disableimplicitframeworkreferences).
### `char` marshalling
Marshalling of `char` will only be supported with `StringMarshalling.Utf16` or as `UnmanagedType.U2` or `UnmanagedType.I2`. It will not be supported when configured with any of the following:
- - [`UnmanagedType.U1` or `UnmanagedType.I1`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.unmanagedtype)
+ - [`UnmanagedType.U1` or `UnmanagedType.I1`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.unmanagedtype)
- `StringMarshalling.Utf8` will not be supported.
- - No explicit marshalling information - either `LibraryImportAttribute.StringMarshalling` or [`MarshalAsAttribute`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute)
+ - No explicit marshalling information - either `LibraryImportAttribute.StringMarshalling` or [`MarshalAsAttribute`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute)
-In the built-in system, marshalling with `CharSet.Ansi` and `CharSet.None` used the [system default Windows ANSI code page](https://docs.microsoft.com/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte) when on Windows and took the first byte of the UTF-8 encoding on non-Windows platforms. The above reasoning also applies to marshalling of a `char` as `UnmanagedType.U1` and `UnmanagedType.I1`. All approaches are fundamentally flawed and therefore not supported. If a single-byte character is expected to be marshalled it is left to the caller to convert a .NET `char` into a single `byte` prior to calling the native function.
+In the built-in system, marshalling with `CharSet.Ansi` and `CharSet.None` used the [system default Windows ANSI code page](https://learn.microsoft.com/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte) when on Windows and took the first byte of the UTF-8 encoding on non-Windows platforms. The above reasoning also applies to marshalling of a `char` as `UnmanagedType.U1` and `UnmanagedType.I1`. All approaches are fundamentally flawed and therefore not supported. If a single-byte character is expected to be marshalled it is left to the caller to convert a .NET `char` into a single `byte` prior to calling the native function.
For `CharSet.Auto`, the built-in system relied upon detection at runtime of the platform when determining the targeted encoding. Performing this check in generated code violates the "pay-for-play" principle. Given that there are no scenarios for this feature in `NetCoreApp` it will not be supported.
### `string` marshalling
Marshalling of `string` will not be supported when configured with any of the following:
- - [`UnmanagedType.VBByRefStr`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.unmanagedtype)
- - No explicit marshalling information - either `LibraryImportAttribute.StringMarshalling` or [`MarshalAsAttribute`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute)
+ - [`UnmanagedType.VBByRefStr`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.unmanagedtype)
+ - No explicit marshalling information - either `LibraryImportAttribute.StringMarshalling` or [`MarshalAsAttribute`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute)
-When converting from native to managed, the built-in system would throw a [`MarshalDirectiveException`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.marshaldirectiveexception) if the string's length is over 0x7ffffff0. The generated marshalling code will no longer perform this check.
+When converting from native to managed, the built-in system would throw a [`MarshalDirectiveException`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.marshaldirectiveexception) if the string's length is over 0x7ffffff0. The generated marshalling code will no longer perform this check.
-In the built-in system, marshalling a `string` contains an optimization for parameters passed by value to allocate on the stack (instead of through [`AllocCoTaskMem`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.marshal.alloccotaskmem)) if the string is below a certain length (MAX_PATH). For UTF-16, this optimization was also applied for parameters passed by read-only reference. The generated marshalling code will include this optimization for read-only reference parameters for non-UTF-16 as well.
+In the built-in system, marshalling a `string` contains an optimization for parameters passed by value to allocate on the stack (instead of through [`AllocCoTaskMem`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.marshal.alloccotaskmem)) if the string is below a certain length (MAX_PATH). For UTF-16, this optimization was also applied for parameters passed by read-only reference. The generated marshalling code will include this optimization for read-only reference parameters for non-UTF-16 as well.
-When marshalling as [ANSI](https://docs.microsoft.com/windows/win32/intl/code-pages) on Windows (using `UnmanagedType.LPStr`):
+When marshalling as [ANSI](https://learn.microsoft.com/windows/win32/intl/code-pages) on Windows (using `UnmanagedType.LPStr`):
- Best-fit mapping will be disabled and no exception will be thrown for unmappable characters. In the built-in system, this behaviour was configured through [`DllImportAttribute.BestFitMapping`] and [`DllImportAttribute.ThrowOnUnmappableChar`]. The generated marshalling code will have the equivalent behaviour of `BestFitMapping=false` and `ThrowOnUnmappableChar=false`.
The p/invoke source generator does not provide an equivalent to using `CharSet.Auto` in the built-in system. If platform-dependent behaviour is desired, it is left to the user to define different p/invokes with different marshalling configurations.
@@ -104,27 +104,27 @@ To aid in conversion from `DllImport` to source-generated marshalling, the code-
### Custom marshaller support
-Using a custom marshaller (i.e. [`ICustomMarshaler`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.icustommarshaler)) with the `UnmanagedType.CustomMarshaler` value on `MarshalAsAttribute` is not supported. This also implies `MarshalAsAttribute` fields: [`MarshalTypeRef`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute.marshaltyperef), [`MarshalType`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute.marshaltype), and [`MarshalCookie`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute.marshalcookie) are unsupported.
+Using a custom marshaller (i.e. [`ICustomMarshaler`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.icustommarshaler)) with the `UnmanagedType.CustomMarshaler` value on `MarshalAsAttribute` is not supported. This also implies `MarshalAsAttribute` fields: [`MarshalTypeRef`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute.marshaltyperef), [`MarshalType`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute.marshaltype), and [`MarshalCookie`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute.marshalcookie) are unsupported.
### Array marshalling
-Marshalling of arrays will not be supported when using [`UnmanagedType.SafeArray`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.unmanagedtype). This implies that the following `MarshalAsAttribute` fields are unsupported: [`SafeArraySubType`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute.safearraysubtype) and [`SafeArrayUserDefinedSubType`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute.safearrayuserdefinedsubtype)
+Marshalling of arrays will not be supported when using [`UnmanagedType.SafeArray`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.unmanagedtype). This implies that the following `MarshalAsAttribute` fields are unsupported: [`SafeArraySubType`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute.safearraysubtype) and [`SafeArrayUserDefinedSubType`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute.safearrayuserdefinedsubtype)
-Specifying array-specific marshalling members on the `MarshalAsAttribute` such as [`SizeConst`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute.sizeconst), [`ArraySubType`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute.arraysubtype), and [`SizeParamIndex`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute.sizeparamindex) with non-array `UnmanagedType` types is unsupported.
+Specifying array-specific marshalling members on the `MarshalAsAttribute` such as [`SizeConst`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute.sizeconst), [`ArraySubType`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute.arraysubtype), and [`SizeParamIndex`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute.sizeparamindex) with non-array `UnmanagedType` types is unsupported.
Only single-dimensional arrays are supported for source generated marshalling.
-In the source-generated marshalling, arrays will be allocated on the stack (instead of through [`AllocCoTaskMem`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.marshal.alloccotaskmem)) if they are passed by value or by read-only reference if they contain at most 256 bytes of data. The built-in system does not support this optimization for arrays.
+In the source-generated marshalling, arrays will be allocated on the stack (instead of through [`AllocCoTaskMem`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.marshal.alloccotaskmem)) if they are passed by value or by read-only reference if they contain at most 256 bytes of data. The built-in system does not support this optimization for arrays.
In the built-in system, marshalling a `char` array by value with `CharSet.Unicode` would default to also marshalling data out. In the source-generated marshalling, the `char` array must be marked with the `[Out]` attribute for data to be marshalled out by value.
### `in` keyword
-For some types - blittable or Unicode `char` - passed by read-only reference via the [`in` keyword](https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/in-parameter-modifier), the built-in system simply pins the parameter. The generated marshalling code does the same, such that there is no behavioural difference. A consequence of this behaviour is that any modifications made by the invoked function will be reflected in the caller. It is left to the user to avoid the situation in which `in` is used for a parameter that will actually be modified by the invoked function.
+For some types - blittable or Unicode `char` - passed by read-only reference via the [`in` keyword](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/in-parameter-modifier), the built-in system simply pins the parameter. The generated marshalling code does the same, such that there is no behavioural difference. A consequence of this behaviour is that any modifications made by the invoked function will be reflected in the caller. It is left to the user to avoid the situation in which `in` is used for a parameter that will actually be modified by the invoked function.
### `LCIDConversion` support
-[`LCIDConversionAttribute`](`https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.lcidconversionattribute`) will not be supported for methods marked with `LibraryImportAttribute`.
+[`LCIDConversionAttribute`](`https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.lcidconversionattribute`) will not be supported for methods marked with `LibraryImportAttribute`.
### `[In, Out]` Attributes
@@ -137,11 +137,11 @@ Support for struct marshalling in the source-generated marshalling is described
### Unsupported types
Unlike the built-in system, the source generator does not support marshalling for the following types:
-- [`CriticalHandle`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.criticalhandle)
-- [`HandleRef`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.handleref)
-- [`StringBuilder`](https://docs.microsoft.com/dotnet/api/system.text.stringbuilder)
+- [`CriticalHandle`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.criticalhandle)
+- [`HandleRef`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.handleref)
+- [`StringBuilder`](https://learn.microsoft.com/dotnet/api/system.text.stringbuilder)
-The source generator also does not support marshalling objects using the following [`UnmanagedType`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.unmanagedtype) values:
+The source generator also does not support marshalling objects using the following [`UnmanagedType`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.unmanagedtype) values:
- `UnmanagedType.Interface`
- `UnmanagedType.IDispatch`
- `UnmanagedType.IInspectable`
diff --git a/docs/design/libraries/LibraryImportGenerator/Pipeline.md b/docs/design/libraries/LibraryImportGenerator/Pipeline.md
index bd38953951751..9414e8d51b636 100644
--- a/docs/design/libraries/LibraryImportGenerator/Pipeline.md
+++ b/docs/design/libraries/LibraryImportGenerator/Pipeline.md
@@ -8,11 +8,11 @@ The P/Invoke source generator is responsible for finding all methods marked with
1. [Generate the corresponding P/Invoke](#pinvoke)
1. Add the generated source to the compilation.
-The pipeline uses the Roslyn [Syntax APIs](https://docs.microsoft.com/dotnet/api/microsoft.codeanalysis.csharp.syntax) to create the generated code. This imposes some structure for the marshalling generators and allows for easier inspection or modification (if desired) of the generated code.
+The pipeline uses the Roslyn [Syntax APIs](https://learn.microsoft.com/dotnet/api/microsoft.codeanalysis.csharp.syntax) to create the generated code. This imposes some structure for the marshalling generators and allows for easier inspection or modification (if desired) of the generated code.
## Symbol and metadata processing
-The generator processes the method's `LibraryImportAttribute` data, the method's parameter and return types, and the metadata on them (e.g. [`LCIDConversionAttribute`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.lcidconversionattribute), [`MarshalAsAttribute`][MarshalAsAttribute], [struct marshalling attributes](StructMarshalling.md)). This information is used to determine the corresponding native type for each managed parameter/return type and how they will be marshalled.
+The generator processes the method's `LibraryImportAttribute` data, the method's parameter and return types, and the metadata on them (e.g. [`LCIDConversionAttribute`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.lcidconversionattribute), [`MarshalAsAttribute`][MarshalAsAttribute], [struct marshalling attributes](StructMarshalling.md)). This information is used to determine the corresponding native type for each managed parameter/return type and how they will be marshalled.
A [`TypePositionInfo`][src-TypePositionInfo] is created for each type that needs to be marshalled. For each parameter and return type, this captures the managed type, managed and native positions (return or index in parameter list), and marshalling information.
@@ -154,7 +154,7 @@ To help enable developers to use the full model described in the [Struct Marshal
### `SetLastError=true`
-The stub code generation also handles [`SetLastError=true`][SetLastError] behaviour. This configuration indicates that system error code ([`errno`](https://en.wikipedia.org/wiki/Errno.h) on Unix, [`GetLastError`](https://docs.microsoft.com/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror) on Windows) should be stored after the native invocation, such that it can be retrieved using [`Marshal.GetLastWin32Error`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.marshal.getlastwin32error).
+The stub code generation also handles [`SetLastError=true`][SetLastError] behaviour. This configuration indicates that system error code ([`errno`](https://en.wikipedia.org/wiki/Errno.h) on Unix, [`GetLastError`](https://learn.microsoft.com/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror) on Windows) should be stored after the native invocation, such that it can be retrieved using [`Marshal.GetLastWin32Error`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.marshal.getlastwin32error).
This means that, rather than simply invoke the native method, the generated stub will:
@@ -229,16 +229,16 @@ static partial byte Method__PInvoke__(ushort* s);
[src-StubCodeContext]: /src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/StubCodeContext.cs
[src-TypePositionInfo]: /src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypePositionInfo.cs
-[DllImportAttribute]: https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute
-[MarshalAsAttribute]: https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute
-[InAttribute]: https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.inattribute
-[OutAttribute]: https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.outattribute
-
-[BestFitMapping]: https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.bestfitmapping
-[CallingConvention]: https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.callingconvention
-[CharSet]: https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.charset
-[EntryPoint]: https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.entrypoint
-[ExactSpelling]: https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.exactspelling
-[PreserveSig]: https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.preservesig
-[SetLastError]: https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.setlasterror
-[ThrowOnUnmappableChar]: https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.throwonunmappablechar
+[DllImportAttribute]: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute
+[MarshalAsAttribute]: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.marshalasattribute
+[InAttribute]: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.inattribute
+[OutAttribute]: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.outattribute
+
+[BestFitMapping]: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.bestfitmapping
+[CallingConvention]: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.callingconvention
+[CharSet]: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.charset
+[EntryPoint]: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.entrypoint
+[ExactSpelling]: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.exactspelling
+[PreserveSig]: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.preservesig
+[SetLastError]: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.setlasterror
+[ThrowOnUnmappableChar]: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute.throwonunmappablechar
diff --git a/docs/design/libraries/LibraryImportGenerator/StructMarshalling.md b/docs/design/libraries/LibraryImportGenerator/StructMarshalling.md
index 24bc5dbb4a75a..0d285f9287062 100644
--- a/docs/design/libraries/LibraryImportGenerator/StructMarshalling.md
+++ b/docs/design/libraries/LibraryImportGenerator/StructMarshalling.md
@@ -282,7 +282,7 @@ The P/Invoke source generator (as well as the struct source generator when neste
If a structure type does not meet the requirements to not require marshalling or does not have the `NativeMarshallingAttribute` applied at the type definition, the user can supply a `MarshalUsingAttribute` at the marshalling location (field, parameter, or return value) with a native type matching the same requirements as `NativeMarshallingAttribute`'s native type.
-All generated stubs will be marked with [`SkipLocalsInitAttribute`](https://docs.microsoft.com/dotnet/api/system.runtime.compilerservices.skiplocalsinitattribute) on supported frameworks. This does require attention when performing custom marshalling as the state of stub allocated memory will be in an undefined state.
+All generated stubs will be marked with [`SkipLocalsInitAttribute`](https://learn.microsoft.com/dotnet/api/system.runtime.compilerservices.skiplocalsinitattribute) on supported frameworks. This does require attention when performing custom marshalling as the state of stub allocated memory will be in an undefined state.
### Special case: Transparent Structures
diff --git a/docs/design/mono/debugger.md b/docs/design/mono/debugger.md
index 2268d81bf1047..6ad08fc09c8da 100644
--- a/docs/design/mono/debugger.md
+++ b/docs/design/mono/debugger.md
@@ -2,7 +2,7 @@
## Overview
-The details of launching a Debugger session for a Blazor WebAssembly application is described [here](https://docs.microsoft.com/en-us/aspnet/core/blazor/debug?view=aspnetcore-6.0&tabs=visual-studio).
+The details of launching a Debugger session for a Blazor WebAssembly application is described [here](https://learn.microsoft.com/aspnet/core/blazor/debug?view=aspnetcore-6.0&tabs=visual-studio).
## Debugger Attributes
Web Assembly Debugger supports usage of following attributes:
@@ -18,7 +18,7 @@ Web Assembly Debugger supports usage of following attributes:
- Stepping In/Over: results in an additional stepping need to proceed to the next line.
- __System.Diagnostics.DebuggerDisplay__
- __System.Diagnostics.DebuggerTypeProxy__
-- __System.Diagnostics.DebuggerBrowsable__ ([doc](https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.debuggerbrowsableattribute?view=net-6.0))
+- __System.Diagnostics.DebuggerBrowsable__ ([doc](https://learn.microsoft.com/dotnet/api/system.diagnostics.debuggerbrowsableattribute?view=net-6.0))
- Collapsed - displayed normally.
- RootHidden:
- Simple type - not displayed in the debugger window.
diff --git a/docs/design/mono/diagnostics-tracing.md b/docs/design/mono/diagnostics-tracing.md
index 9d1f668871cae..898ea1a3a96ff 100644
--- a/docs/design/mono/diagnostics-tracing.md
+++ b/docs/design/mono/diagnostics-tracing.md
@@ -19,13 +19,13 @@ Existing diagnostic tooling only supports `NamedPipes`/`UnixDomainSockets`, so i
For more details around diagnostic scenarios, see:
-https://docs.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-counters
+https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-counters
-https://docs.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-trace
+https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-trace
-https://docs.microsoft.com/en-us/dotnet/core/diagnostics/event-counter-perf
+https://learn.microsoft.com/dotnet/core/diagnostics/event-counter-perf
-https://docs.microsoft.com/en-us/dotnet/core/diagnostics/debug-highcpu
+https://learn.microsoft.com/dotnet/core/diagnostics/debug-highcpu
## Building an application including diagnostic tracing support
@@ -380,7 +380,7 @@ NOTE, iOS only support use of loopback interface when running DiagnosticServer i
### Application running single file based EventPipe session
-If application supports controlled runtime shutdown, `mono_jit_cleanup` gets called before terminating process, it is possible to run a single file based EventPipe session using environment variables as described in https://docs.microsoft.com/en-us/dotnet/core/diagnostics/eventpipe#trace-using-environment-variables. In .net6 an additional variable has been added, `DOTNET_EventPipeOutputStreaming`, making sure data is periodically flushed into the output file.
+If application supports controlled runtime shutdown, `mono_jit_cleanup` gets called before terminating process, it is possible to run a single file based EventPipe session using environment variables as described in https://learn.microsoft.com/dotnet/core/diagnostics/eventpipe#trace-using-environment-variables. In .net6 an additional variable has been added, `DOTNET_EventPipeOutputStreaming`, making sure data is periodically flushed into the output file.
If application doesn't support controlled runtime shutdown, this mode won't work, since it requires rundown events, only emitted when closing session and flushing memory manager. If application doesn't call `mono_jit_cleanup` before terminating, generated nettrace file will lack rundown events needed to produce callstacks including symbols.
@@ -493,9 +493,9 @@ Combining different sessions including different GC information opens up ability
Collected events retrieved over EventPipe sessions is stored in a nettrace file that can be analyzed using tooling like PerfView, Speedscope, Chronium or Visual Studio:
-https://docs.microsoft.com/en-us/dotnet/core/diagnostics/debug-highcpu?tabs=windows#trace-generation
+https://learn.microsoft.com/dotnet/core/diagnostics/debug-highcpu?tabs=windows#trace-generation
-https://docs.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-trace#dotnet-trace-convert
+https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-trace#dotnet-trace-convert
https://github.com/dotnet/diagnostics/blob/main/documentation/tutorial/app_running_slow_highcpu.md
diff --git a/docs/design/mono/mono-library-mode.md b/docs/design/mono/mono-library-mode.md
index 42288fa22a447..f6c6a98e5a746 100644
--- a/docs/design/mono/mono-library-mode.md
+++ b/docs/design/mono/mono-library-mode.md
@@ -3,16 +3,16 @@ Library Mode on Mono
# Background
-For many native applications, accessibility to bountiful APIs from .NET runtime libraries can save developers from "reinventing the wheel" in the target platform's native language. That is where [interoperability](https://learn.microsoft.com/en-us/dotnet/csharp/advanced-topics/interop/) comes in handy to access modern .NET APIs from the native side. The .NET runtime libraries require the .NET runtime to function properly, and integrating the entire .NET ecosystem may prove cumbersome and unnecessary. Instead, for a smaller footprint and more seamless experience, the runtime and custom managed code invoking .NET APIs can be bundled into a library for direct consumption. In line with [Native code interop with Native AOT](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/interop), as of .NET 8, the [mono runtime supports a library mode](https://github.com/dotnet/runtime/issues/79377) enabling mobile developers to leverage modern .NET APIs in their mobile applications with a single static or shared library.
+For many native applications, accessibility to bountiful APIs from .NET runtime libraries can save developers from "reinventing the wheel" in the target platform's native language. That is where [interoperability](https://learn.microsoft.com/dotnet/csharp/advanced-topics/interop/) comes in handy to access modern .NET APIs from the native side. The .NET runtime libraries require the .NET runtime to function properly, and integrating the entire .NET ecosystem may prove cumbersome and unnecessary. Instead, for a smaller footprint and more seamless experience, the runtime and custom managed code invoking .NET APIs can be bundled into a library for direct consumption. In line with [Native code interop with Native AOT](https://learn.microsoft.com/dotnet/core/deploying/native-aot/interop), as of .NET 8, the [mono runtime supports a library mode](https://github.com/dotnet/runtime/issues/79377) enabling mobile developers to leverage modern .NET APIs in their mobile applications with a single static or shared library.
Note: The library generated from Mono's Library Mode containing custom managed code and the mono runtime will, for brevity, be referred to as the mono library.
# How it works
The core components of mono's library mode that enables interoperability between native and managed code are as follows:
-1. [UnmanagedCallersOnlyAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.unmanagedcallersonlyattribute?view=net-7.0) which allows native code to directly call managed methods.
-2. [Direct Platform Invoke (P/Invoke)](https://learn.microsoft.com/en-us/dotnet/standard/native-interop/pinvoke) which allows managed code to directly call native functions.
-3. The mono runtime which facilitates the above interop directions among its other responsibilities as a [managed runtime](https://learn.microsoft.com/en-us/dotnet/core/introduction#runtime).
+1. [UnmanagedCallersOnlyAttribute](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.unmanagedcallersonlyattribute?view=net-7.0) which allows native code to directly call managed methods.
+2. [Direct Platform Invoke (P/Invoke)](https://learn.microsoft.com/dotnet/standard/native-interop/pinvoke) which allows managed code to directly call native functions.
+3. The mono runtime which facilitates the above interop directions among its other responsibilities as a [managed runtime](https://learn.microsoft.com/dotnet/core/introduction#runtime).
Being able to call managed .NET APIs from a native application has many usecases, including reducing the need to rewrite logic in the native language when there is no native counterpart. In order to call managed code leveraging these .NET APIs, the native application needs to recognize the corresponding symbols. Once custom managed code is compiled into managed assemblies, the Mono AOT Compiler processes them to generate [native-to-managed wrappers](https://github.com/dotnet/runtime/blob/43d164d8d65d163fef0de185eb11cfa0b1291919/src/mono/mono/mini/aot-compiler.c#L5446-L5498) for all methods decorated with [`UnmanagedCallersOnlyAttribute`](https://github.com/dotnet/runtime/pull/79424). These native-to-managed wrappers have entrypoint symbols specified by the corresponding `UnmanagedCallersOnlyAttribute`, allowing native code to call them directly. So once the mono library is linked/loaded into the native application, the Mono AOT Compiled assemblies should be [preloaded by the mono runtime](https://github.com/dotnet/runtime/blob/43d164d8d65d163fef0de185eb11cfa0b1291919/src/tasks/LibraryBuilder/Templates/preloaded-assemblies.c#L10) once the mono runtime is initialized in order to enable calling managed methods from the native side of the application.
diff --git a/docs/design/mono/profiled-aot.md b/docs/design/mono/profiled-aot.md
index 80e36b9e9c02b..2d88a7c9ea584 100644
--- a/docs/design/mono/profiled-aot.md
+++ b/docs/design/mono/profiled-aot.md
@@ -9,9 +9,9 @@ Mobile applications built using .NET typically leverage the Mono runtime to load
The advantages of Profiled AOT stem from its flexibility to AOT select code paths, leaving the rest to be compiled on the fly by the JIT compiler or Mono Interpreter. With an analysis of an application's trace, a record capturing a sequence of events during the application's execution, profiles can be generated to tailor optimizations for each application and environment. For example, profiles may target frequently executed (hot) code paths, minimizing the amount of runtime compilations and reducing application size, which are especially important in environments where full AOT compilation would strain storage space. Moreover, profiles may target startup code to optimize startup performance.
-Within .NET, traces can be collected by [diagnostic tooling](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/eventpipe#tools-that-use-eventpipe) that use the [EventPipe](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/eventpipe) runtime component. [Existing diagnostic tooling only supports `NamedPipes`/`UnixDomainSockets`](https://github.com/dotnet/runtime/blob/main/docs/design/mono/diagnostics-tracing.md), so the [diagnostics tool dotnet-dsrouter](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-dsrouter) is required to bridge the EventPipe-based diagnostic tooling with .NET applications on mobile platforms and other remote sandboxed environments.
+Within .NET, traces can be collected by [diagnostic tooling](https://learn.microsoft.com/dotnet/core/diagnostics/eventpipe#tools-that-use-eventpipe) that use the [EventPipe](https://learn.microsoft.com/dotnet/core/diagnostics/eventpipe) runtime component. [Existing diagnostic tooling only supports `NamedPipes`/`UnixDomainSockets`](https://github.com/dotnet/runtime/blob/main/docs/design/mono/diagnostics-tracing.md), so the [diagnostics tool dotnet-dsrouter](https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-dsrouter) is required to bridge the EventPipe-based diagnostic tooling with .NET applications on mobile platforms and other remote sandboxed environments.
-Events collected by EventPipe-based diagnostic tooling are emitted with a [`.nettrace` file format](https://github.com/microsoft/perfview/blob/main/src/TraceEvent/EventPipe/EventPipeFormat.md). Among the [various events supported by Mono runtime](https://github.com/dotnet/runtime/blob/main/src/mono/mono/eventpipe/gen-eventing-event-inc.lst), [method jitting and method loading](https://github.com/dotnet/runtime/blob/096b2499fe6939d635c35edaa607a180eb578fbb/src/mono/mono/eventpipe/gen-eventing-event-inc.lst#L39-L41) are crucial to [inform the Mono AOT Compiler what methods to AOT](https://github.com/dotnet/runtime/blob/6b67caaedfbfeaf7707478e50ccc9e8bc929e591/src/mono/mono/mini/aot-compiler.c#L13818-L13880). To collect a trace containing such events, it is imperative that dotnet-trace is provided either the appropriate [event provider](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/well-known-event-providers) with [keyword flags](https://github.com/dotnet/runtime/blob/c59aef7622c9a2499abb1b7d262ed0c90f4b0c7f/src/coreclr/vm/ClrEtwAll.man#L14-L92) through `--providers` or the appropriate list of keywords through `--clrevents`. That way, the [events relevant to the keywords are captured](https://github.com/dotnet/runtime/blob/c59aef7622c9a2499abb1b7d262ed0c90f4b0c7f/src/coreclr/vm/ClrEtwAll.man#L3133). In the example workflows below, `--providers Microsoft-Windows-DotNETRuntime:0x1F000080018:5` is used.
+Events collected by EventPipe-based diagnostic tooling are emitted with a [`.nettrace` file format](https://github.com/microsoft/perfview/blob/main/src/TraceEvent/EventPipe/EventPipeFormat.md). Among the [various events supported by Mono runtime](https://github.com/dotnet/runtime/blob/main/src/mono/mono/eventpipe/gen-eventing-event-inc.lst), [method jitting and method loading](https://github.com/dotnet/runtime/blob/096b2499fe6939d635c35edaa607a180eb578fbb/src/mono/mono/eventpipe/gen-eventing-event-inc.lst#L39-L41) are crucial to [inform the Mono AOT Compiler what methods to AOT](https://github.com/dotnet/runtime/blob/6b67caaedfbfeaf7707478e50ccc9e8bc929e591/src/mono/mono/mini/aot-compiler.c#L13818-L13880). To collect a trace containing such events, it is imperative that dotnet-trace is provided either the appropriate [event provider](https://learn.microsoft.com/dotnet/core/diagnostics/well-known-event-providers) with [keyword flags](https://github.com/dotnet/runtime/blob/c59aef7622c9a2499abb1b7d262ed0c90f4b0c7f/src/coreclr/vm/ClrEtwAll.man#L14-L92) through `--providers` or the appropriate list of keywords through `--clrevents`. That way, the [events relevant to the keywords are captured](https://github.com/dotnet/runtime/blob/c59aef7622c9a2499abb1b7d262ed0c90f4b0c7f/src/coreclr/vm/ClrEtwAll.man#L3133). In the example workflows below, `--providers Microsoft-Windows-DotNETRuntime:0x1F000080018:5` is used.
Profiles [ingested by the Mono AOT Compiler](https://github.com/dotnet/runtime/blob/6b67caaedfbfeaf7707478e50ccc9e8bc929e591/src/tasks/AotCompilerTask/MonoAOTCompiler.cs#L174) are generated through .NET runtime's [`dotnet-pgo` tool](https://github.com/dotnet/runtime/blob/main/docs/design/features/dotnet-pgo.md). As such, profiles passed to the Mono AOT Compiler are expected to adhere to the [`.mibc` file format](https://github.com/dotnet/runtime/blob/main/src/coreclr/tools/dotnet-pgo/dotnet-pgo-experiment.md#mibc-file-format). The Mono AOT Compiler [reads `.mibc` profiles](https://github.com/dotnet/runtime/blob/c59aef7622c9a2499abb1b7d262ed0c90f4b0c7f/src/mono/mono/mini/aot-compiler.c#L14085-L14162) to determine [which methods to AOT](https://github.com/dotnet/runtime/blob/6b67caaedfbfeaf7707478e50ccc9e8bc929e591/src/mono/mono/mini/aot-compiler.c#L13818-L13880) when compiling CIL assemblies.
@@ -34,8 +34,8 @@ As the [`.mibc` profile](https://github.com/dotnet/runtime/blob/main/src/coreclr
### Requirements:
- [Prerequisites](https://github.com/dotnet/runtime/blob/main/docs/workflow/testing/libraries/testing-android.md#prerequisites)
- [Building mono and libs](https://github.com/dotnet/runtime/blob/main/docs/workflow/testing/libraries/testing-android.md#building-libs-and-tests-for-android)
-- [dotnet-dsrouter](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-dsrouter)
-- [dotnet-trace](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-trace)
+- [dotnet-dsrouter](https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-dsrouter)
+- [dotnet-trace](https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-trace)
### Tracing (if not using provided .nettrace/.mibc files)
(informational) [Understanding diagnostics_tracing runtime component](https://github.com/dotnet/runtime/blob/main/docs/design/mono/diagnostics-tracing.md)
diff --git a/docs/design/specs/Ecma-335-Augments.md b/docs/design/specs/Ecma-335-Augments.md
index e9722759ea80e..f6b8f9b964eff 100644
--- a/docs/design/specs/Ecma-335-Augments.md
+++ b/docs/design/specs/Ecma-335-Augments.md
@@ -1069,7 +1069,7 @@ Note about creating zero-based, one-dimensional arrays in section III.4.21 "newo
## API documentation
-API documentation included in partition IV: Profiles and Libraries is superseded by the actively maintained API documentation in https://github.com/dotnet/dotnet-api-docs repo. The documentation is published at https://docs.microsoft.com/en-us/dotnet/api/.
+API documentation included in partition IV: Profiles and Libraries is superseded by the actively maintained API documentation in https://github.com/dotnet/dotnet-api-docs repo. The documentation is published at https://learn.microsoft.com/dotnet/api/.
The incorrect description of `System.Array.Initialize` API in section "II.13.2 Initializing value types" is replaced with "The Base Class Library provides the method System.Array.Initialize (see Partition IV) to initialize every element of an array of unboxed value types by calling its parameterless instance constructor."
diff --git a/docs/design/tools/illink/trimmed-assemblies.md b/docs/design/tools/illink/trimmed-assemblies.md
index bf2b9273d4fc5..ac8e03fddc2aa 100644
--- a/docs/design/tools/illink/trimmed-assemblies.md
+++ b/docs/design/tools/illink/trimmed-assemblies.md
@@ -66,7 +66,7 @@ This shows how Blazor (or a developer) can hook into the build to opt assemblies
### Other options
-.NET 5 introduced a host of additional SDK options that map directly to the underlying illink options. The full list is documented at https://docs.microsoft.com/en-us/dotnet/core/deploying/trimming-options.
+.NET 5 introduced a host of additional SDK options that map directly to the underlying illink options. The full list is documented at https://learn.microsoft.com/dotnet/core/deploying/trimming-options.
## .NET 6
@@ -100,7 +100,7 @@ This ItemGroup contains assembly names that get opted into trimming via `IsTrimm
```
-The above opts `MyAssembly.dll` into trimming. Note that the ItemGroup should contain assembly names without an extension, similar to [`TrimmerRootAssembly`](https://docs.microsoft.com/en-us/dotnet/core/deploying/trimming-options#root-assemblies). Before .NET 6 this would have been done with a target:
+The above opts `MyAssembly.dll` into trimming. Note that the ItemGroup should contain assembly names without an extension, similar to [`TrimmerRootAssembly`](https://learn.microsoft.com/dotnet/core/deploying/trimming-options#root-assemblies). Before .NET 6 this would have been done with a target:
```xml
```
-(Documentation for configuring feeds is [here](https://docs.microsoft.com/en-us/nuget/consume-packages/configuring-nuget-behavior).)
+(Documentation for configuring feeds is [here](https://learn.microsoft.com/nuget/consume-packages/configuring-nuget-behavior).)
## Setup the project
diff --git a/docs/project/glossary.md b/docs/project/glossary.md
index 8e1de1bef9646..55d59730bd572 100644
--- a/docs/project/glossary.md
+++ b/docs/project/glossary.md
@@ -15,25 +15,25 @@ terminology.
| BBT | Microsoft internal early version of C/C++ PGO. See https://www.microsoft.com/windows/cse/bit_projects.mspx. |
| BOTR | Book Of The Runtime. |
| BCL | Base Class Library. A set of `System.*` (and to a limited extent `Microsoft.*`) libraries that make up the lower layer of the .NET library stack. |
-| CIL | Common Intermediate Language. Equivalent to IL, also equivalent to [MSIL](https://docs.microsoft.com/dotnet/standard/managed-execution-process#compiling-to-msil). |
+| CIL | Common Intermediate Language. Equivalent to IL, also equivalent to [MSIL](https://learn.microsoft.com/dotnet/standard/managed-execution-process#compiling-to-msil). |
| CLI | Command Line Interface, or Common Language Infastructure. |
-| CLR | [Common Language Runtime](https://docs.microsoft.com/dotnet/standard/clr). |
+| CLR | [Common Language Runtime](https://learn.microsoft.com/dotnet/standard/clr). |
| COMPlus | An early name for the .NET platform, back when it was envisioned as a successor to the COM platform (hence, "COM+"). Used in various places in the CLR infrastructure, most prominently as a common prefix for the names of internal configuration settings. Note that this is different from the product that eventually ended up being named [COM+](https://msdn.microsoft.com/library/windows/desktop/ms685978.aspx). |
| COR | [Common Object Runtime](http://www.danielmoth.com/Blog/mscorlibdll.aspx). The name of .NET before it was named .NET. |
| CoreFX | Core Framework. Original project name for open source and cross-platform version of [.NET runtime libraries](https://github.com/dotnet/runtime/tree/main/src/libraries) |
| DAC | Data Access Component. An abstraction layer over the internal structures in the runtime. |
-| EE | [Execution Engine](https://docs.microsoft.com/dotnet/standard/managed-execution-process#running_code). |
+| EE | [Execution Engine](https://learn.microsoft.com/dotnet/standard/managed-execution-process#running_code). |
| GC | [Garbage Collector](https://github.com/dotnet/runtime/blob/main/docs/design/coreclr/botr/garbage-collection.md). |
| IBC | Instrumented Block Counts - used as extension (`*.ibc`) for old PGO files. |
| IJW | "It Just Works" - Codename for [C++/CLI](https://learn.microsoft.com/cpp/dotnet/dotnet-programming-with-cpp-cli-visual-cpp) managed/native interop |
| IPC | Inter-Process Communication. |
-| IL | Intermediate Language. Equivalent to CIL, also equivalent to [MSIL](https://docs.microsoft.com/dotnet/standard/managed-execution-process#compiling-to-msil). |
+| IL | Intermediate Language. Equivalent to CIL, also equivalent to [MSIL](https://learn.microsoft.com/dotnet/standard/managed-execution-process#compiling-to-msil). |
| JIT | [Just-in-Time](https://github.com/dotnet/runtime/blob/main/docs/design/coreclr/jit/ryujit-overview.md) compiler. RyuJIT is the code name for the next generation Just-in-Time(aka "JIT") for the .NET runtime. |
| LCG | Lightweight Code Generation. An early name for [dynamic methods](https://github.com/dotnet/runtime/blob/main/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs). |
| MD | MetaData. |
-| MDA | Managed Debugging Assistant - see [details](https://docs.microsoft.com/dotnet/framework/debug-trace-profile/diagnosing-errors-with-managed-debugging-assistants) (Note: Not in .NET Core, equivalent diagnostic functionality is made available on a case-by-case basis, e.g. [#9418](https://github.com/dotnet/runtime/issues/9418)) |
+| MDA | Managed Debugging Assistant - see [details](https://learn.microsoft.com/dotnet/framework/debug-trace-profile/diagnosing-errors-with-managed-debugging-assistants) (Note: Not in .NET Core, equivalent diagnostic functionality is made available on a case-by-case basis, e.g. [#9418](https://github.com/dotnet/runtime/issues/9418)) |
| MIBC | Managed Instrumented Block Counts - used as extension (`*.mibc`) for managed PGO files. |
-| MSIL | [Microsoft Intermediate Language](https://docs.microsoft.com/dotnet/standard/managed-execution-process#compiling-to-msil).Common Intermediate Language. Equivalent to IL, also equivalent to CIL. |
+| MSIL | [Microsoft Intermediate Language](https://learn.microsoft.com/dotnet/standard/managed-execution-process#compiling-to-msil).Common Intermediate Language. Equivalent to IL, also equivalent to CIL. |
| NGen | Native Image Generator. |
| NYI | Not Yet Implemented. |
| PAL | [Platform Adaptation Layer](http://archive.oreilly.com/pub/a/dotnet/2002/03/04/rotor.html). Provides an abstraction layer between the runtime and the operating system. |
@@ -43,17 +43,17 @@ terminology.
| ProjectN | Codename for the first version of [.NET Native for UWP](https://msdn.microsoft.com/vstudio/dotnetnative.aspx). |
| R2R | Ready-to-Run. A flavor of native images - command line switch of [crossgen](../workflow/building/coreclr/crossgen.md). |
| Redhawk | Codename for experimental minimal managed code runtime that evolved into [CoreRT](https://github.com/dotnet/corert/). |
-| SDK | Software Development Kit. The [.NET SDK](https://docs.microsoft.com/dotnet/core/sdk) contains the .NET CLI, .NET libraries and runtime, and the dotnet driver. |
-| SEH | [Structured Exception Handling](https://docs.microsoft.com/windows/win32/debug/structured-exception-handling). Unified mechanism for handling hardware and software exceptions on Windows. |
+| SDK | Software Development Kit. The [.NET SDK](https://learn.microsoft.com/dotnet/core/sdk) contains the .NET CLI, .NET libraries and runtime, and the dotnet driver. |
+| SEH | [Structured Exception Handling](https://learn.microsoft.com/windows/win32/debug/structured-exception-handling). Unified mechanism for handling hardware and software exceptions on Windows. |
| SOS | [Son of Strike](https://learn.microsoft.com/dotnet/framework/tools/sos-dll-sos-debugging-extension). The debugging extension for DbgEng based debuggers. Uses the DAC as an abstraction layer for its operation. The obscure name derives from the original nickname for the CLR team at Microsoft: "Lightning". The team built a debugging tool humorously named "Strike", and a subset of that dubbed "Son of Strike". |
| SPCL | `System.Private.CoreLib` - the lowest managed assembly in the libraries stack that contains `System.Object`, `String`, etc. |
| SuperPMI | JIT component test framework (super fast JIT testing - it mocks/replays EE in EE-JIT interface) - see [SuperPMI details](https://github.com/dotnet/runtime/blob/main/src/coreclr/tools/superpmi/readme.md). |
| SVR | The CLR used to be built as two variants, with one called "mscorsvr.dll", to mean the "server" version. In particular, it contained the server GC implementation, which was intended for multi-threaded apps capable of taking advantage of multiple processors. In the .NET Framework 2 release, the two variants were merged into "mscorwks.dll". The WKS version was the default, however the SVR version remained available. |
-| TFM | [Target Framework Moniker](https://docs.microsoft.com/dotnet/standard/frameworks) such as `net6.0` or `netstandard2.0`. |
+| TFM | [Target Framework Moniker](https://learn.microsoft.com/dotnet/standard/frameworks) such as `net6.0` or `netstandard2.0`. |
| TPA | Trusted Platform Assemblies used to be a special set of assemblies that comprised the platform assemblies, when it was originally designed. As of today, it is simply the set of assemblies known to constitute the application. |
| URT | Universal Runtime. Ancient name for what ended up being .NET, is used in the WinError facility name FACILITY_URT. |
| UTC | [Universal Tuple Compiler](https://blogs.msdn.microsoft.com/vcblog/2013/06/12/optimizing-c-code-overview/). The Microsoft C++ optimizer back-end that starts by converting the information from the FrontEnd into tuples – a binary stream of instructions. |
-| UWP | [Universal Windows Platform (UWP)](https://docs.microsoft.com/en-us/windows/uwp/get-started/universal-application-platform-guide) is a platform-homogeneous application architecture available on every device that runs Windows 10. |
+| UWP | [Universal Windows Platform (UWP)](https://learn.microsoft.com/windows/uwp/get-started/universal-application-platform-guide) is a platform-homogeneous application architecture available on every device that runs Windows 10. |
| VSD | [Virtual Stub Dispatch](../design/coreclr/botr/virtual-stub-dispatch.md). Technique of using stubs for virtual method invocations instead of the traditional virtual method table. |
| VM | Virtual machine. |
| WKS | The CLR used to be built as two variants, with one called "mscorwks.dll", to mean the "workstation" version. In particular, it contained the client GC implementation, which was intended for single-threaded apps, independent of how many processors were on the machine. In the .NET Framework 2 release, the two variants were merged into "mscorwks.dll". The WKS version was the default, however the SVR version remained available. |
@@ -173,18 +173,18 @@ produces binaries in the ReadyToRun file format.
### NGen
-[NGen](https://docs.microsoft.com/en-us/dotnet/framework/tools/ngen-exe-native-image-generator)
+[NGen](https://learn.microsoft.com/dotnet/framework/tools/ngen-exe-native-image-generator)
is AOT technology included in .NET Framework. It usually compiles code at install time on the machine where
the code will be executed.
### Full AOT
-[Full AOT](https://docs.microsoft.com/en-us/xamarin/ios/internals/architecture) is used
+[Full AOT](https://learn.microsoft.com/xamarin/ios/internals/architecture) is used
by Mono runtime in environments that prohibit fallback to JIT.
### Hybrid AOT
-[Hybrid AOT](https://docs.microsoft.com/en-us/xamarin/mac/internals/aot#hybrid-aot) is used
+[Hybrid AOT](https://learn.microsoft.com/xamarin/mac/internals/aot#hybrid-aot) is used
by Mono runtime in environments that allow fallback to JIT or need IL interpreter.
### Native AOT
@@ -301,8 +301,8 @@ and enabling support for running WPF on .NET Core (Windows Only).
[xunit]: https://github.com/xunit
[mc.dot.net]: https://mc.dot.net/
[ECMA-355]: https://www.ecma-international.org/publications-and-standards/standards/ecma-335
-[dotnet-tooling]: https://docs.microsoft.com/en-us/dotnet/core/tools/
-[dlr-architecture]: https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/dynamic-language-runtime-overview#dlr-architecture
+[dotnet-tooling]: https://learn.microsoft.com/dotnet/core/tools/
+[dlr-architecture]: https://learn.microsoft.com/dotnet/framework/reflection-and-codedom/dynamic-language-runtime-overview#dlr-architecture
[dlr-source]: https://github.com/IronLanguages/dlr
[WinForms]: https://github.com/dotnet/winforms
[Wpf]: https://github.com/dotnet/wpf
diff --git a/docs/project/list-of-diagnostics.md b/docs/project/list-of-diagnostics.md
index 41d5a78f3f179..fa109f5726797 100644
--- a/docs/project/list-of-diagnostics.md
+++ b/docs/project/list-of-diagnostics.md
@@ -35,8 +35,8 @@ The acceptance criteria for adding an obsoletion includes:
* A bot will automatically apply the `needs-breaking-change-doc-created` label when the `breaking-change` label is detected
* Follow up with the breaking change process to communicate and document the breaking change
* In the breaking-change issue filed in [dotnet/docs](https://github.com/dotnet/docs), specifically mention that this breaking change is an obsoletion with a `SYSLIB` diagnostic id
- * The documentation team will produce a PR that adds the obsoletion to the [SYSLIB warnings](https://docs.microsoft.com/en-us/dotnet/core/compatibility/syslib-obsoletions) page
- * That PR will also add a new URL specific to this diagnostic ID; e.g. [SYSLIB0001](https://docs.microsoft.com/en-us/dotnet/core/compatibility/syslib-warnings/syslib0001)
+ * The documentation team will produce a PR that adds the obsoletion to the [SYSLIB warnings](https://learn.microsoft.com/dotnet/core/compatibility/syslib-obsoletions) page
+ * That PR will also add a new URL specific to this diagnostic ID; e.g. [SYSLIB0001](https://learn.microsoft.com/dotnet/core/compatibility/syslib-warnings/syslib0001)
* Connect with `@gewarren` or `@BillWagner` with any questions
* Register the `SYSLIB0###` URL in `aka.ms`
* The vanity name will be `dotnet-warnings/syslib0###`
@@ -145,7 +145,7 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL
| __`SYSLIB1024`__ | Argument is using the unsupported out parameter modifier |
| __`SYSLIB1025`__ | Multiple logging methods cannot use the same event name within a class |
| __`SYSLIB1026`__ | C# language version not supported by the logging source generator. |
-| __`SYSLIB1027`__ | _`SYSLIB1001`-`SYSLIB1029` reserved for logging._ |
+| __`SYSLIB1027`__ | Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field |
| __`SYSLIB1028`__ | _`SYSLIB1001`-`SYSLIB1029` reserved for logging._ |
| __`SYSLIB1029`__ | _`SYSLIB1001`-`SYSLIB1029` reserved for logging._ |
| __`SYSLIB1030`__ | JsonSourceGenerator did not generate serialization metadata for type |
diff --git a/docs/project/strong-name-signing.md b/docs/project/strong-name-signing.md
index 269bb102c4ad2..e7bde0aab6880 100644
--- a/docs/project/strong-name-signing.md
+++ b/docs/project/strong-name-signing.md
@@ -1,26 +1,26 @@
Strong Name Signing
===================
-All .NET Core assemblies are [strong-named](https://docs.microsoft.com/en-us/dotnet/framework/app-domains/strong-named-assemblies). We do this for two reasons:
+All .NET Core assemblies are [strong-named](https://learn.microsoft.com/dotnet/framework/app-domains/strong-named-assemblies). We do this for two reasons:
1. _Compatibility_. We want to maintain type identity with previous versions of our assemblies that have shipped across various versions of our platforms. Removing a strong-name from an assembly is a breaking change, and would break the ability to consume and run libraries built against the previous identities.
-2. _Serviceability_. When running on .NET Framework some of .NET Core assemblies ship locally ("app-local") with the application, this is in contrast to other framework assemblies that are placed in the [GAC](https://docs.microsoft.com/en-us/dotnet/framework/app-domains/gac). To be able to service these libraries for critical security updates, we make use of the [app-local servicing](https://blogs.msdn.microsoft.com/dotnet/2014/01/22/net-4-5-1-supports-microsoft-security-updates-for-net-nuget-libraries/) feature which requires that assemblies have strong-names.
+2. _Serviceability_. When running on .NET Framework some of .NET Core assemblies ship locally ("app-local") with the application, this is in contrast to other framework assemblies that are placed in the [GAC](https://learn.microsoft.com/dotnet/framework/app-domains/gac). To be able to service these libraries for critical security updates, we make use of the [app-local servicing](https://blogs.msdn.microsoft.com/dotnet/2014/01/22/net-4-5-1-supports-microsoft-security-updates-for-net-nuget-libraries/) feature which requires that assemblies have strong-names.
## FAQ
### 1. Microsoft strong-names their assemblies, should I?
For the most part, the majority of applications do not need strong-names. Strong-names are left over from previous eras of .NET where [sandboxing](https://en.wikipedia.org/wiki/Sandbox_(computer_security)) needed to differentiate between code that was trusted, versus code that was untrusted. However in recent years, sandboxing via AppDomains, especially to [isolate ASP.NET web applications](https://support.microsoft.com/en-us/help/2698981/asp-net-partial-trust-does-not-guarantee-application-isolation), is no longer guaranteed and is not recommended.
-However, strong-names are still required in applications in some rare situations, most of which are called out on this page: [Strong-Named Assemblies](https://docs.microsoft.com/en-us/dotnet/framework/app-domains/strong-named-assemblies).
+However, strong-names are still required in applications in some rare situations, most of which are called out on this page: [Strong-Named Assemblies](https://learn.microsoft.com/dotnet/framework/app-domains/strong-named-assemblies).
-Because of the viral nature of strong-naming, it is recommended that publicly published .NET libraries are strong-named. Not strong-naming a .NET library excludes anyone who does need to strong-name their application or library from using it. Read more about .NET libraries and strong-naming in the [.NET Library Guidance](https://docs.microsoft.com/dotnet/standard/library-guidance/strong-naming).
+Because of the viral nature of strong-naming, it is recommended that publicly published .NET libraries are strong-named. Not strong-naming a .NET library excludes anyone who does need to strong-name their application or library from using it. Read more about .NET libraries and strong-naming in the [.NET Library Guidance](https://learn.microsoft.com/dotnet/standard/library-guidance/strong-naming).
### 2. I really, _really_ need to strong-name, what kinds of issues will I run into?
There are three major problems that developers run into after strong naming their assemblies:
-1. _Binding Policy_. When developers talk about strong-names, they are usually conflating it with the strict binding policy of the .NET Framework that kicks in _when_ you strong-name. This binding policy is problematic because it forces, by default, an exact match between reference and version, and requires developers to author complex [binding redirects](https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/bindingredirect-element) when they don't. In recent versions of Visual Studio, however, we've added [Automatic Binding Redirection](https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/how-to-enable-and-disable-automatic-binding-redirection) as an attempt to reduce pain of this policy on developers. On top of this, all newer platforms, including _Silverlight_, _WinRT-based platforms_ (Phone and Store), _.NET Native_ and _ASP.NET 5_ this policy has been loosened, allowing later versions of an assembly to satisfy earlier references, thereby completely removing the need to ever write binding redirects on those platforms.
+1. _Binding Policy_. When developers talk about strong-names, they are usually conflating it with the strict binding policy of the .NET Framework that kicks in _when_ you strong-name. This binding policy is problematic because it forces, by default, an exact match between reference and version, and requires developers to author complex [binding redirects](https://learn.microsoft.com/dotnet/framework/configure-apps/file-schema/runtime/bindingredirect-element) when they don't. In recent versions of Visual Studio, however, we've added [Automatic Binding Redirection](https://learn.microsoft.com/dotnet/framework/configure-apps/how-to-enable-and-disable-automatic-binding-redirection) as an attempt to reduce pain of this policy on developers. On top of this, all newer platforms, including _Silverlight_, _WinRT-based platforms_ (Phone and Store), _.NET Native_ and _ASP.NET 5_ this policy has been loosened, allowing later versions of an assembly to satisfy earlier references, thereby completely removing the need to ever write binding redirects on those platforms.
2. _Virality_. Once you've strong-named an assembly, you can only statically reference other strong-named assemblies.
-3. _No drop-in replacement_. This is a problem for open source libraries where the strong-name private key is not checked into the repository. This means that developers are unable to build to their own version of the library and then use it as a drop-in replacement without recompiling _all_ consuming libraries up stack to pick up the new identity. This is extremely problematic for libraries, such as Json.NET, which have large incoming dependencies. Firstly, we would recommend that these open source projects check-in their private key (remember, [strong-names are used for identity, and not for security](https://docs.microsoft.com/en-us/dotnet/framework/app-domains/strong-named-assemblies)). Failing that, however, we've introduced a new concept called [Public Signing](public-signing.md) that enables developers to build drop-in replacements without needing access to the strong-name private key. This is the mechanism that .NET Core libraries use by default.
+3. _No drop-in replacement_. This is a problem for open source libraries where the strong-name private key is not checked into the repository. This means that developers are unable to build to their own version of the library and then use it as a drop-in replacement without recompiling _all_ consuming libraries up stack to pick up the new identity. This is extremely problematic for libraries, such as Json.NET, which have large incoming dependencies. Firstly, we would recommend that these open source projects check-in their private key (remember, [strong-names are used for identity, and not for security](https://learn.microsoft.com/dotnet/framework/app-domains/strong-named-assemblies)). Failing that, however, we've introduced a new concept called [Public Signing](public-signing.md) that enables developers to build drop-in replacements without needing access to the strong-name private key. This is the mechanism that .NET Core libraries use by default.
diff --git a/docs/tools/illink/README.md b/docs/tools/illink/README.md
index 7aed29d0ea76d..c837328dbdd73 100644
--- a/docs/tools/illink/README.md
+++ b/docs/tools/illink/README.md
@@ -3,7 +3,7 @@
This folder includes several documents that explain both high-level and low-level concepts about the IL trimmer and related tools.
## Official Docs
-View the official trimming docs at [docs.microsoft.com](https://docs.microsoft.com/en-us/dotnet/core/deploying/trimming/trim-self-contained)
+View the official trimming docs at [learn.microsoft.com](https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-self-contained)
## Usage Docs
- [MSBuild Integration](illink-tasks.md)
diff --git a/docs/tools/illink/custom-steps.md b/docs/tools/illink/custom-steps.md
index d7ce8576c9068..9adf1687cb1ac 100644
--- a/docs/tools/illink/custom-steps.md
+++ b/docs/tools/illink/custom-steps.md
@@ -3,7 +3,7 @@
The IL trimmer behaviour can be altered not only using existing options but also by
adding custom steps to the processing pipeline. This advanced technique is not necessary
for most scenarious but can be used by additional framework or SDKs which need very
-custom behaviour or have other special needs for the processing.
+custom behaviour or have other special requirements for the processing.
## Building
diff --git a/docs/tools/illink/illink-options.md b/docs/tools/illink/illink-options.md
index 76d8e26837671..1ed9928c08fc7 100644
--- a/docs/tools/illink/illink-options.md
+++ b/docs/tools/illink/illink-options.md
@@ -110,7 +110,7 @@ Each feature can be controlled independently using `--feature NAME value` option
The list of available feature names is framework-dependent and can vary between different
framework versions.
-The list of controllable features for .NET Core is available at https://docs.microsoft.com/en-us/dotnet/core/run-time-config/.
+The list of controllable features for .NET Core is available at https://learn.microsoft.com/dotnet/core/run-time-config/.
### Using custom substitutions
diff --git a/docs/tools/illink/serialization.md b/docs/tools/illink/serialization.md
index d93f50bd8db3e..648b9a226cb9d 100644
--- a/docs/tools/illink/serialization.md
+++ b/docs/tools/illink/serialization.md
@@ -1,6 +1,6 @@
# Serialization
-Trimming tools cannot analyze the patterns typically used by reflection-based serializers. Such serializers should be annotated with `RequiresUnreferencedCodeAttribute`, and using them in a trimmed app will likely not work (or will work unpredictably). Trimming tools will produce static analysis [warnings](https://docs.microsoft.com/dotnet/core/deploying/trimming-options#analysis-warnings) for these patterns.
+Trimming tools cannot analyze the patterns typically used by reflection-based serializers. Such serializers should be annotated with `RequiresUnreferencedCodeAttribute`, and using them in a trimmed app will likely not work (or will work unpredictably). Trimming tools will produce static analysis [warnings](https://learn.microsoft.com/dotnet/core/deploying/trimming-options#analysis-warnings) for these patterns.
If possible, avoid using reflection-based serializers with trimming, and prefer solutions based on source generators where the serialized types and all required members are statically referenced.
@@ -129,12 +129,12 @@ Most features of reflection-based serializers will not work even with these heur
- Serializing/deserializing types which are not attributed and don't have attributed members
- Passing `typeof(MyType)` (directly or indirectly) into serializer constructors or methods
- "Known type" mechanisms, such as:
- - [`KnownTypeAttribute`](https://docs.microsoft.com/dotnet/api/system.runtime.serialization.knowntypeattribute?view=net-5.0)
- - [`DataContractSerializer.KnownTypes`](https://docs.microsoft.com/dotnet/api/system.runtime.serialization.datacontractserializer.knowntypes?view=net-5.0)
- - `extraTypes` argument of the [`XmlSerializer ctor`](https://docs.microsoft.com/dotnet/api/system.xml.serialization.xmlserializer.-ctor?view=net-5.0#System_Xml_Serialization_XmlSerializer__ctor_System_Type_System_Type___)
+ - [`KnownTypeAttribute`](https://learn.microsoft.com/dotnet/api/system.runtime.serialization.knowntypeattribute?view=net-5.0)
+ - [`DataContractSerializer.KnownTypes`](https://learn.microsoft.com/dotnet/api/system.runtime.serialization.datacontractserializer.knowntypes?view=net-5.0)
+ - `extraTypes` argument of the [`XmlSerializer ctor`](https://learn.microsoft.com/dotnet/api/system.xml.serialization.xmlserializer.-ctor?view=net-5.0#System_Xml_Serialization_XmlSerializer__ctor_System_Type_System_Type___)
- Serializing types which implement special interfaces
- - [`ISerializable`](https://docs.microsoft.com/dotnet/api/system.runtime.serialization.iserializable?view=net-5.0)
- - [`IXmlSerializable`](https://docs.microsoft.com/dotnet/api/system.xml.serialization.ixmlserializable?view=net-5.0)
+ - [`ISerializable`](https://learn.microsoft.com/dotnet/api/system.runtime.serialization.iserializable?view=net-5.0)
+ - [`IXmlSerializable`](https://learn.microsoft.com/dotnet/api/system.xml.serialization.ixmlserializable?view=net-5.0)
- Serializer-specific handling of collection types
- - Types which implement [`ICollection`](https://docs.microsoft.com/dotnet/standard/serialization/examples-of-xml-serialization#serializing-a-class-that-implements-the-icollection-interface)
- - Deserializing [`collection interfaces`](https://docs.microsoft.com/dotnet/framework/wcf/feature-details/collection-types-in-data-contracts#using-collection-interface-types-and-read-only-collections) into serializer-specific default types
+ - Types which implement [`ICollection`](https://learn.microsoft.com/dotnet/standard/serialization/examples-of-xml-serialization#serializing-a-class-that-implements-the-icollection-interface)
+ - Deserializing [`collection interfaces`](https://learn.microsoft.com/dotnet/framework/wcf/feature-details/collection-types-in-data-contracts#using-collection-interface-types-and-read-only-collections) into serializer-specific default types
diff --git a/docs/workflow/building/coreclr/cross-building.md b/docs/workflow/building/coreclr/cross-building.md
index 7bbe28abb6410..d053569cfbcb3 100644
--- a/docs/workflow/building/coreclr/cross-building.md
+++ b/docs/workflow/building/coreclr/cross-building.md
@@ -142,7 +142,7 @@ If you're building the cross-components in powershell, you'll need to wrap `"-DC
## Cross-Building using Docker
-When it comes to building, Docker offers the most flexibility when it comes to targeting different Linux platforms and other similar Unix-based ones, like FreeBSD. This is thanks to the multiple existing Docker images already configured for doing such cross-platform building, and Docker's ease of use of running out of the box on Windows machines with [WSL](https://docs.microsoft.com/windows/wsl/about) enabled, installed, and up and running, as well as Linux machines.
+When it comes to building, Docker offers the most flexibility when it comes to targeting different Linux platforms and other similar Unix-based ones, like FreeBSD. This is thanks to the multiple existing Docker images already configured for doing such cross-platform building, and Docker's ease of use of running out of the box on Windows machines with [WSL](https://learn.microsoft.com/windows/wsl/about) enabled, installed, and up and running, as well as Linux machines.
### Cross-Compiling for ARM32 and ARM64 with Docker
diff --git a/docs/workflow/building/coreclr/linux-instructions.md b/docs/workflow/building/coreclr/linux-instructions.md
index 3acec5e95ad9a..f19bcfbd1e7e2 100644
--- a/docs/workflow/building/coreclr/linux-instructions.md
+++ b/docs/workflow/building/coreclr/linux-instructions.md
@@ -19,7 +19,7 @@ As mentioned in the [Linux requirements doc](/docs/workflow/requirements/linux-r
Building using Docker will require that you choose the correct image for your environment.
-Note that the OS is strictly speaking not important. For example if you are on Ubuntu 20.04 and build using the Ubuntu 18.04 x64 image there should be no issues. You can even use Linux images on a Windows OS if you have [WSL](https://docs.microsoft.com/windows/wsl/about) enabled. However, note that you can't run multiple OS's on the same _Docker Daemon_, as it takes resources from the underlying kernel as needed. In other words, you can run either Linux on WSL, or Windows containers. You have to switch between them if you need both, and restart Docker.
+Note that the OS is strictly speaking not important. For example if you are on Ubuntu 20.04 and build using the Ubuntu 18.04 x64 image there should be no issues. You can even use Linux images on a Windows OS if you have [WSL](https://learn.microsoft.com/windows/wsl/about) enabled. However, note that you can't run multiple OS's on the same _Docker Daemon_, as it takes resources from the underlying kernel as needed. In other words, you can run either Linux on WSL, or Windows containers. You have to switch between them if you need both, and restart Docker.
The target architecture is more important, as building arm32 using the x64 image will not work. There will be missing _rootfs_ components required by the build. See [Docker Images](#docker-images) below, for more information on choosing an image to build with.
diff --git a/docs/workflow/ci/coreclr-ci-health.md b/docs/workflow/ci/coreclr-ci-health.md
index 79be9ac1bfebf..b26bfcab8db21 100644
--- a/docs/workflow/ci/coreclr-ci-health.md
+++ b/docs/workflow/ci/coreclr-ci-health.md
@@ -13,7 +13,7 @@ Note that this document focuses on coreclr testing in `dotnet/runtime`.
#### Terminology
-In order to follow some of the terminology used, there is an expected familiarity of Azure DevOps required. For an in depth guide with Azure DevOps pipeline definitions, please see: https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema.
+In order to follow some of the terminology used, there is an expected familiarity of Azure DevOps required. For an in depth guide with Azure DevOps pipeline definitions, please see: https://learn.microsoft.com/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema.
The most common terminology and most important are the different containers work happens in.
diff --git a/docs/workflow/debugging/coreclr/debugging-runtime.md b/docs/workflow/debugging/coreclr/debugging-runtime.md
index 6edce3c7646e0..e9e1881063d63 100644
--- a/docs/workflow/debugging/coreclr/debugging-runtime.md
+++ b/docs/workflow/debugging/coreclr/debugging-runtime.md
@@ -113,7 +113,7 @@ Visual Studio Code instructions coming soon!
Under normal circumstances, SOS usually comes shipped with Windbg, so no additional installation is required. However, if this is not the case for you, you want to use another version, or any other circumstance that requires you to install it separately/additionally, here are two links with useful information on how to get it set up:
-* The official [Microsoft docs on SOS](https://docs.microsoft.com/dotnet/core/diagnostics/dotnet-sos).
+* The official [Microsoft docs on SOS](https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-sos).
* The instructions at the [diagnostics repo](https://github.com/dotnet/diagnostics/blob/master/documentation/installing-sos-windows-instructions.md).
For more information on SOS commands click [here](https://github.com/dotnet/diagnostics/blob/master/documentation/sos-debugging-extension-windows.md).
@@ -140,7 +140,7 @@ If for some reason `System.Private.CoreLib.dll` is missing, you can rebuild it w
For Linux and macOS, you have to install SOS by yourself, as opposed to Windows' Windbg. The instructions are very similar however, and you can find them on these two links:
-* The official [Microsoft docs on SOS](https://docs.microsoft.com/dotnet/core/diagnostics/dotnet-sos).
+* The official [Microsoft docs on SOS](https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-sos).
* The instructions at the [diagnostics repo](https://github.com/dotnet/diagnostics/blob/master/documentation/installing-sos-instructions.md).
It might also be the case that you would need the latest changes in SOS, or you're working with a not-officially-supported scenario that actually works. The most common occurrence of this scenario is when using macOS Arm64. In this case, you have to build SOS from the diagnostics repo (linked above). Once you have it done, then simply load it to your `lldb`. More details in the following section.
@@ -227,11 +227,11 @@ Starting with Visual Studio 2022 version 17.5, Visual Studio will validate that
> Unable to attach to CoreCLR. Signature validation failed for a .NET Runtime Debugger library because the file is unsigned.
>
-> This error is expected if you are working with non-official releases of .NET (example: daily builds from https://github.com/dotnet/installer). See https://aka.ms/vs/unsigned-dotnet-debugger-lib for more information.
+> This error is expected if you are working with non-official releases of .NET (example: daily builds from https://github.com/dotnet/sdk). See https://aka.ms/vs/unsigned-dotnet-debugger-lib for more information.
If the target process is using a .NET Runtime that is either from a daily build, or one that you built on your own computer, this error will show up. **NOTE**: This error should never happen for official builds of the .NET Runtime from Microsoft. So don’t disable the validation if you expect to be using a .NET Runtime supported by Microsoft.
There are three ways to configure Visual Studio to disable signature validation:
-1. The [`DOTNET_ROOT` environment variable](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables#dotnet_root-dotnet_rootx86): if Visual Studio is started from a command prompt where `DOTNET_ROOT` is set, it will ignore unsigned .NET runtime debugger libraries which are under the `DOTNET_ROOT` directory.
+1. The [`DOTNET_ROOT` environment variable](https://learn.microsoft.com/dotnet/core/tools/dotnet-environment-variables#dotnet_root-dotnet_rootx86): if Visual Studio is started from a command prompt where `DOTNET_ROOT` is set, it will ignore unsigned .NET runtime debugger libraries which are under the `DOTNET_ROOT` directory.
2. The `VSDebugger_ValidateDotnetDebugLibSignatures` environment variable: If you want to temporarily disable signature validation, run `set VSDebugger_ValidateDotnetDebugLibSignatures=0` in a command prompt, and start Visual Studio (devenv.exe) from this command prompt.
3. Set the `ValidateDotnetDebugLibSignatures` registry key: To disable signature validation on a more permanent basis, you can set the VS registry key to turn it off. To do so, open a Developer Command Prompt, and run `Common7\IDE\VsRegEdit.exe set local HKCU Debugger\EngineSwitches ValidateDotnetDebugLibSignatures dword 0`
diff --git a/docs/workflow/debugging/libraries/unix-instructions.md b/docs/workflow/debugging/libraries/unix-instructions.md
index 7e6b7700839af..5063b1f414719 100644
--- a/docs/workflow/debugging/libraries/unix-instructions.md
+++ b/docs/workflow/debugging/libraries/unix-instructions.md
@@ -5,7 +5,7 @@ CoreFX can be debugged on unix using both lldb and visual studio code
## Using lldb and SOS
-- Install SOS and lldb. See https://github.com/dotnet/diagnostics/blob/main/documentation/sos.md and https://docs.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-sos for setup instructions.
+- Install SOS and lldb. See https://github.com/dotnet/diagnostics/blob/main/documentation/sos.md and https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-sos for setup instructions.
- Run the test using msbuild at least once with `/t:Test`.
## Debugging core dumps with lldb
diff --git a/docs/workflow/requirements/windows-requirements.md b/docs/workflow/requirements/windows-requirements.md
index 86c1fca3a7f3d..7eb85bec22fcc 100644
--- a/docs/workflow/requirements/windows-requirements.md
+++ b/docs/workflow/requirements/windows-requirements.md
@@ -20,7 +20,7 @@ Here are the components you will need to install and setup to work with the repo
### Enable Long Paths
-The runtime repository requires long paths to be enabled. Follow [the instructions provided here](https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation#enable-long-paths-in-windows-10-version-1607-and-later) to enable that feature.
+The runtime repository requires long paths to be enabled. Follow [the instructions provided here](https://learn.microsoft.com/windows/win32/fileio/maximum-file-path-limitation#enable-long-paths-in-windows-10-version-1607-and-later) to enable that feature.
If using Git for Windows you might need to also configure long paths there. Using an administrator terminal simply type:
@@ -42,7 +42,7 @@ Note that Visual Studio and the development tools described below are required,
* To build the tests, you will need some additional components:
* **C++/CLI support for v143 build tools (Latest)**.
-A `.vsconfig` file is included in the root of the _dotnet/runtime_ repository that includes all components needed to build the _dotnet/runtime_ repository. You can [import `.vsconfig` in your Visual Studio installer](https://docs.microsoft.com/visualstudio/install/import-export-installation-configurations?view=vs-2022#import-a-configuration) to install all necessary components.
+A `.vsconfig` file is included in the root of the _dotnet/runtime_ repository that includes all components needed to build the _dotnet/runtime_ repository. You can [import `.vsconfig` in your Visual Studio installer](https://learn.microsoft.com/visualstudio/install/import-export-installation-configurations?view=vs-2022#import-a-configuration) to install all necessary components.
### Build Tools
@@ -89,7 +89,7 @@ The _dotnet/runtime_ repository requires at least Git 2.22.0.
While not strictly needed to build or test this repository, having the .NET SDK installed lets you browse solution files in this repository with Visual Studio and use the `dotnet.exe` command to run .NET applications in the 'normal' way.
-We use this in the [build testing with the installed SDK](/docs/workflow/testing/using-your-build-with-installed-sdk.md), and [build testing with dev shipping packages](/docs/workflow/testing/using-dev-shipping-packages.md) instructions. The minimum required version of the SDK is specified in the [global.json file](https://github.com/dotnet/runtime/blob/main/global.json#L3). You can find the installers and binaries for latest development builds of .NET SDK in the [installer repo](https://github.com/dotnet/installer#installers-and-binaries).
+We use this in the [build testing with the installed SDK](/docs/workflow/testing/using-your-build-with-installed-sdk.md), and [build testing with dev shipping packages](/docs/workflow/testing/using-dev-shipping-packages.md) instructions. The minimum required version of the SDK is specified in the [global.json file](https://github.com/dotnet/runtime/blob/main/global.json#L3). You can find the installers and binaries for latest development builds of .NET SDK in the [sdk repo](https://github.com/dotnet/sdk#installing-the-sdk).
Alternatively, to avoid modifying your machine state, you can use the repository's locally acquired SDK by passing in the solution to load via the `-vs` switch. For example:
diff --git a/docs/workflow/testing/host/testing.md b/docs/workflow/testing/host/testing.md
index a217d1dd0ab98..65f2f92b0d8c3 100644
--- a/docs/workflow/testing/host/testing.md
+++ b/docs/workflow/testing/host/testing.md
@@ -64,12 +64,12 @@ By default, the above command will also build the tests before running them. To
If all tests have not been previously run, make sure the [test context](#test-context) is set up for the test library.
-Tests from a specific test project can be run using [`dotnet test`](https://docs.microsoft.com/dotnet/core/tools/dotnet-test) targeting the built test binary. For example:
+Tests from a specific test project can be run using [`dotnet test`](https://learn.microsoft.com/dotnet/core/tools/dotnet-test) targeting the built test binary. For example:
```
dotnet test artifacts/bin/HostActivation.Tests/Debug/net6.0/HostActivation.Tests.dll --filter category!=failing
```
-To filter to specific tests within the test library, use the [filter options](https://docs.microsoft.com/dotnet/core/tools/dotnet-test#filter-option-details) available for `dotnet test`. For example:
+To filter to specific tests within the test library, use the [filter options](https://learn.microsoft.com/dotnet/core/tools/dotnet-test#filter-option-details) available for `dotnet test`. For example:
```
dotnet test artifacts/bin/HostActivation.Tests/Debug/net6.0/HostActivation.Tests.dll --filter "DependencyResolution&category!=failing"
```
diff --git a/docs/workflow/testing/host/using-apphost.md b/docs/workflow/testing/host/using-apphost.md
index 764dc6ad68e58..f3a3f5309df10 100644
--- a/docs/workflow/testing/host/using-apphost.md
+++ b/docs/workflow/testing/host/using-apphost.md
@@ -25,6 +25,6 @@ Alternatives to this method include copying the desired apphost to the appropria
# Pointing at a local .NET root
-For a [framework-dependent application](https://docs.microsoft.com/dotnet/core/deploying/#publish-framework-dependent), you can set the `DOTNET_ROOT` environment variable to point at a local .NET layout.
+For a [framework-dependent application](https://learn.microsoft.com/dotnet/core/deploying/#publish-framework-dependent), you can set the `DOTNET_ROOT` environment variable to point at a local .NET layout.
The [libraries tests](../libraries/testing.md) construct and use such a layout based on your local runtime, host, and libraries build as part of the `libs.pretest` subset. To use that layout, set `DOTNET_ROOT=/artifacts/bin/testhost/net8.0---` and then run the .NET application.
diff --git a/docs/workflow/testing/testing-managed-tools.md b/docs/workflow/testing/testing-managed-tools.md
index 6e2fddbdbd773..589e689a1803d 100644
--- a/docs/workflow/testing/testing-managed-tools.md
+++ b/docs/workflow/testing/testing-managed-tools.md
@@ -41,5 +41,5 @@ The `dotnet-test` xunit filter mechanisms work to run a single test or a subset
```
The above command runs all tests whose fully-qualified name contains the substring `MyTest`. See
-[dotnet test - Run selective unit tests](https://learn.microsoft.com/en-us/dotnet/core/testing/selective-unit-tests?pivots=mstest#syntax)
+[dotnet test - Run selective unit tests](https://learn.microsoft.com/dotnet/core/testing/selective-unit-tests?pivots=mstest#syntax)
for the full syntax.
diff --git a/docs/workflow/testing/using-dev-shipping-packages.md b/docs/workflow/testing/using-dev-shipping-packages.md
index 6510b43d22474..1d801886e8a9f 100644
--- a/docs/workflow/testing/using-dev-shipping-packages.md
+++ b/docs/workflow/testing/using-dev-shipping-packages.md
@@ -40,7 +40,7 @@ This will place several installers, Nuget packages, compressed archives, and oth
### Acquire the latest development .NET SDK
-The [installer repo](https://github.com/dotnet/installer) has downloads to all nightly builds for all the currently supported platforms. Find the one that matches your machine and download it.
+The [sdk repo](https://github.com/dotnet/sdk#installing-the-sdk) has downloads to all nightly builds for all the currently supported platforms. Find the one that matches your machine and download it.
To setup the nightly SDK, you can either install it to your machine or use a portable build. If you downloaded the _installer_, then just follow the usual installation instructions, and you're done.
@@ -80,7 +80,7 @@ This config file will require a handful of modifications to work as we need it t
-
+
diff --git a/docs/workflow/testing/using-your-build-with-installed-sdk.md b/docs/workflow/testing/using-your-build-with-installed-sdk.md
index a2716ea9e7aad..200f035250fcd 100644
--- a/docs/workflow/testing/using-your-build-with-installed-sdk.md
+++ b/docs/workflow/testing/using-your-build-with-installed-sdk.md
@@ -30,7 +30,7 @@ This guide focuses on the first of the bullet points described above. For the ot
### Acquire the latest development .NET SDK
-The [installer repo](https://github.com/dotnet/installer) has downloads to all nightly builds for all the currently supported platforms. Find the one that matches your machine and download it.
+The [sdk repo](https://github.com/dotnet/sdk#installing-the-sdk) has downloads to all nightly builds for all the currently supported platforms. Find the one that matches your machine and download it.
To setup the nightly SDK, you can either install it to your machine or use a portable build. If you downloaded the _installer_, then just follow the usual installation instructions, and you're done.
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 9fde4018aacb7..4b3aaaab38bba 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -12,9 +12,9 @@
https://github.com/dotnet/wcf
7f504aabb1988e9a093c1e74d8040bd52feb2f01
-
+
https://github.com/dotnet/emsdk
- b0e8c5f3800bbaa46221ff26b3748f0a2b486f8c
+ fae2c9534679912d43304de91e622f63e7110919
https://github.com/dotnet/llvm-project
@@ -68,111 +68,111 @@
7a4a59f9f66baf6711a6ce2de01d3b2c62ed72d8
-
+
https://github.com/dotnet/emsdk
- b0e8c5f3800bbaa46221ff26b3748f0a2b486f8c
+ fae2c9534679912d43304de91e622f63e7110919
-
+
https://github.com/dotnet/emsdk
- b0e8c5f3800bbaa46221ff26b3748f0a2b486f8c
+ fae2c9534679912d43304de91e622f63e7110919
-
+
https://github.com/dotnet/source-build-reference-packages
- 0df72d85186994facaefcb4eb832b8c8a8e5ae3d
+ 87ebd07371adfe1d8140889c33da692eb2134f1a
-
+
https://github.com/dotnet/source-build-externals
- 59204e5b14e6e197b3c942f992f6e3ec9196e50b
+ 7db00527ef8fbbe61f67e9295beebddf187efff8
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
https://github.com/dotnet/runtime-assets
@@ -332,9 +332,9 @@
https://github.com/dotnet/xharness
8478d1a9a531e6b1cd26fb8c86400e2efbb8f2f3
-
+
https://github.com/dotnet/arcade
- 2001d73c8ff942331a73300ba61fa6164805b231
+ e6b3f32f9855dccbe2447471c8f729b66f17d242
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
@@ -360,17 +360,17 @@
https://github.com/dotnet/runtime-assets
c185f58a7f75bd824a3cd820634cddf27e791d91
-
+
https://github.com/dotnet/roslyn
- 2e1435d1aadd8ddb90a171e207e3cb2ae67253f2
+ 37b70f27ecf6578ad0b74d04406036b03ab90c8f
-
+
https://github.com/dotnet/roslyn
- 2e1435d1aadd8ddb90a171e207e3cb2ae67253f2
+ 37b70f27ecf6578ad0b74d04406036b03ab90c8f
-
+
https://github.com/dotnet/roslyn
- 2e1435d1aadd8ddb90a171e207e3cb2ae67253f2
+ 37b70f27ecf6578ad0b74d04406036b03ab90c8f
https://github.com/dotnet/roslyn-analyzers
@@ -381,9 +381,9 @@
8dccccec1ce3bd2fb532ec77d7e092ab9d684db7
-
+
https://github.com/dotnet/roslyn
- 2e1435d1aadd8ddb90a171e207e3cb2ae67253f2
+ 37b70f27ecf6578ad0b74d04406036b03ab90c8f
diff --git a/eng/Versions.props b/eng/Versions.props
index d76d352b6b508..2d215aba85668 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -11,7 +11,7 @@
7.0.19
6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet8)').Build),25))
preview
- 5
+ 6
false
release
@@ -42,9 +42,9 @@
Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure
they do not break the local dev experience.
-->
- 4.11.0-2.24274.2
- 4.11.0-2.24274.2
- 4.11.0-2.24274.2
+ 4.11.0-3.24301.1
+ 4.11.0-3.24301.1
+ 4.11.0-3.24301.1
9.0.100-preview.5.24272.19
- 9.0.0-beta.24272.5
- 9.0.0-beta.24272.5
- 9.0.0-beta.24272.5
- 9.0.0-beta.24272.5
- 2.6.7-beta.24272.5
- 9.0.0-beta.24272.5
- 2.6.7-beta.24272.5
- 9.0.0-beta.24272.5
- 9.0.0-beta.24272.5
- 9.0.0-beta.24272.5
- 9.0.0-beta.24272.5
- 9.0.0-beta.24272.5
- 9.0.0-beta.24272.5
- 9.0.0-beta.24272.5
- 9.0.0-beta.24272.5
- 9.0.0-beta.24272.5
+ 9.0.0-beta.24281.1
+ 9.0.0-beta.24281.1
+ 9.0.0-beta.24281.1
+ 9.0.0-beta.24281.1
+ 2.6.7-beta.24281.1
+ 9.0.0-beta.24281.1
+ 2.6.7-beta.24281.1
+ 9.0.0-beta.24281.1
+ 9.0.0-beta.24281.1
+ 9.0.0-beta.24281.1
+ 9.0.0-beta.24281.1
+ 9.0.0-beta.24281.1
+ 9.0.0-beta.24281.1
+ 9.0.0-beta.24281.1
+ 9.0.0-beta.24281.1
+ 9.0.0-beta.24281.1
1.4.0
@@ -161,7 +161,7 @@
1.0.0-prerelease.24223.3
2.0.0
- 17.8.0-beta1.23475.2
+ 17.10.0-beta1.24272.1
2.0.0-beta4.23407.1
3.1.7
2.1.0
@@ -235,9 +235,9 @@
Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml
like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-9_0_100_Transport
-->
- 9.0.0-preview.6.24272.2
+ 9.0.0-preview.6.24277.2
$(MicrosoftNETWorkloadEmscriptenCurrentManifest90100TransportVersion)
- 9.0.0-preview.6.24272.2
+ 9.0.0-preview.6.24277.2
1.1.87-gba258badda
1.0.0-v3.14.0.5722
diff --git a/eng/common/SetupNugetSources.ps1 b/eng/common/SetupNugetSources.ps1
index efa2fd72bfaa2..c07f6a52601bd 100644
--- a/eng/common/SetupNugetSources.ps1
+++ b/eng/common/SetupNugetSources.ps1
@@ -1,31 +1,32 @@
-# This file is a temporary workaround for internal builds to be able to restore from private AzDO feeds.
-# This file should be removed as part of this issue: https://github.com/dotnet/arcade/issues/4080
+# This script adds internal feeds required to build commits that depend on internal package sources. For instance,
+# dotnet6-internal would be added automatically if dotnet6 was found in the nuget.config file. In addition also enables
+# disabled internal Maestro (darc-int*) feeds.
+#
+# Optionally, this script also adds a credential entry for each of the internal feeds if supplied. This credential
+# is added via the standard environment variable VSS_NUGET_EXTERNAL_FEED_ENDPOINTS. See
+# https://github.com/microsoft/artifacts-credprovider/tree/v1.1.1?tab=readme-ov-file#environment-variables for more details
#
-# What the script does is iterate over all package sources in the pointed NuGet.config and add a credential entry
-# under for each Maestro managed private feed. Two additional credential
-# entries are also added for the two private static internal feeds: dotnet3-internal and dotnet3-internal-transport.
-#
-# This script needs to be called in every job that will restore packages and which the base repo has
-# private AzDO feeds in the NuGet.config.
-#
-# See example YAML call for this script below. Note the use of the variable `$(dn-bot-dnceng-artifact-feeds-rw)`
-# from the AzureDevOps-Artifact-Feeds-Pats variable group.
-#
-# Any disabledPackageSources entries which start with "darc-int" will be re-enabled as part of this script executing
+# See example call for this script below.
#
# - task: PowerShell@2
-# displayName: Setup Private Feeds Credentials
+# displayName: Setup Internal Feeds
# condition: eq(variables['Agent.OS'], 'Windows_NT')
# inputs:
# filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1
-# arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token
-# env:
-# Token: $(dn-bot-dnceng-artifact-feeds-rw)
+# arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config
+# - task: NuGetAuthenticate@1
+#
+# Note that the NuGetAuthenticate task should be called after SetupNugetSources.
+# This ensures that:
+# - Appropriate creds are set for the added internal feeds (if not supplied to the scrupt)
+# - The credential provider is installed
+#
+# This logic is also abstracted into enable-internal-sources.yml.
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)][string]$ConfigFile,
- [Parameter(Mandatory = $true)][string]$Password
+ [string]$Password
)
$ErrorActionPreference = "Stop"
@@ -34,12 +35,23 @@ Set-StrictMode -Version 2.0
. $PSScriptRoot\tools.ps1
+$feedEndpoints = $null
+
+# If a credential is provided, ensure that we don't overwrite the current set of
+# credentials that may have been provided by a previous call to the credential provider.
+if ($Password -and $null -ne $env:VSS_NUGET_EXTERNAL_FEED_ENDPOINTS) {
+ $feedEndpoints = $env:VSS_NUGET_EXTERNAL_FEED_ENDPOINTS | ConvertFrom-Json
+} elseif ($Password) {
+ $feedEndpoints = @{ endpointCredentials = @() }
+}
+
# Add source entry to PackageSources
-function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Username, $pwd) {
+function AddPackageSource($sources, $SourceName, $SourceEndPoint, $pwd) {
$packageSource = $sources.SelectSingleNode("add[@key='$SourceName']")
- if ($packageSource -eq $null)
+ if ($null -eq $packageSource)
{
+ Write-Host "`tAdding package source" $SourceName
$packageSource = $doc.CreateElement("add")
$packageSource.SetAttribute("key", $SourceName)
$packageSource.SetAttribute("value", $SourceEndPoint)
@@ -48,58 +60,34 @@ function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Usern
else {
Write-Host "Package source $SourceName already present."
}
- AddCredential -Creds $creds -Source $SourceName -Username $Username -pwd $pwd
-}
-
-# Add a credential node for the specified source
-function AddCredential($creds, $source, $username, $pwd) {
- # Looks for credential configuration for the given SourceName. Create it if none is found.
- $sourceElement = $creds.SelectSingleNode($Source)
- if ($sourceElement -eq $null)
- {
- $sourceElement = $doc.CreateElement($Source)
- $creds.AppendChild($sourceElement) | Out-Null
- }
- # Add the node to the credential if none is found.
- $usernameElement = $sourceElement.SelectSingleNode("add[@key='Username']")
- if ($usernameElement -eq $null)
- {
- $usernameElement = $doc.CreateElement("add")
- $usernameElement.SetAttribute("key", "Username")
- $sourceElement.AppendChild($usernameElement) | Out-Null
+ if ($pwd) {
+ $feedEndpoints.endpointCredentials = AddCredential -endpointCredentials $feedEndpoints.endpointCredentials -source $SourceEndPoint -pwd $pwd
}
- $usernameElement.SetAttribute("value", $Username)
+}
- # Add the to the credential if none is found.
- # Add it as a clear text because there is no support for encrypted ones in non-windows .Net SDKs.
- # -> https://github.com/NuGet/Home/issues/5526
- $passwordElement = $sourceElement.SelectSingleNode("add[@key='ClearTextPassword']")
- if ($passwordElement -eq $null)
- {
- $passwordElement = $doc.CreateElement("add")
- $passwordElement.SetAttribute("key", "ClearTextPassword")
- $sourceElement.AppendChild($passwordElement) | Out-Null
+# Add a new feed endpoint credential
+function AddCredential([array]$endpointCredentials, $source, $pwd) {
+ $endpointCredentials += @{
+ endpoint = $source;
+ password = $pwd
}
-
- $passwordElement.SetAttribute("value", $pwd)
+ return $endpointCredentials
}
-function InsertMaestroPrivateFeedCredentials($Sources, $Creds, $Username, $pwd) {
- $maestroPrivateSources = $Sources.SelectNodes("add[contains(@key,'darc-int')]")
+function InsertMaestroInternalFeedCredentials($Sources, $pwd) {
+ $maestroInternalSources = $Sources.SelectNodes("add[contains(@key,'darc-int')]")
- Write-Host "Inserting credentials for $($maestroPrivateSources.Count) Maestro's private feeds."
-
- ForEach ($PackageSource in $maestroPrivateSources) {
- Write-Host "`tInserting credential for Maestro's feed:" $PackageSource.Key
- AddCredential -Creds $creds -Source $PackageSource.Key -Username $Username -pwd $pwd
+ ForEach ($PackageSource in $maestroInternalSources) {
+ Write-Host "`tAdding credential for Maestro's feed:" $PackageSource.Key
+ $feedEndpoints.endpointCredentials = AddCredential -endpointCredentials $feedEndpoints.endpointCredentials -source $PackageSource.value -pwd $pwd
}
}
-function EnablePrivatePackageSources($DisabledPackageSources) {
- $maestroPrivateSources = $DisabledPackageSources.SelectNodes("add[contains(@key,'darc-int')]")
- ForEach ($DisabledPackageSource in $maestroPrivateSources) {
- Write-Host "`tEnsuring private source '$($DisabledPackageSource.key)' is enabled by deleting it from disabledPackageSource"
+function EnableInternalPackageSources($DisabledPackageSources) {
+ $maestroInternalSources = $DisabledPackageSources.SelectNodes("add[contains(@key,'darc-int')]")
+ ForEach ($DisabledPackageSource in $maestroInternalSources) {
+ Write-Host "`tEnsuring internal source '$($DisabledPackageSource.key)' is enabled by deleting it from disabledPackageSource"
# Due to https://github.com/NuGet/Home/issues/10291, we must actually remove the disabled entries
$DisabledPackageSources.RemoveChild($DisabledPackageSource)
}
@@ -110,11 +98,6 @@ if (!(Test-Path $ConfigFile -PathType Leaf)) {
ExitWithExitCode 1
}
-if (!$Password) {
- Write-PipelineTelemetryError -Category 'Build' -Message 'Eng/common/SetupNugetSources.ps1 returned a non-zero exit code. Please supply a valid PAT'
- ExitWithExitCode 1
-}
-
# Load NuGet.config
$doc = New-Object System.Xml.XmlDocument
$filename = (Get-Item $ConfigFile).FullName
@@ -122,35 +105,27 @@ $doc.Load($filename)
# Get reference to or create one if none exist already
$sources = $doc.DocumentElement.SelectSingleNode("packageSources")
-if ($sources -eq $null) {
+if ($null -eq $sources) {
$sources = $doc.CreateElement("packageSources")
$doc.DocumentElement.AppendChild($sources) | Out-Null
}
-# Looks for a node. Create it if none is found.
-$creds = $doc.DocumentElement.SelectSingleNode("packageSourceCredentials")
-if ($creds -eq $null) {
- $creds = $doc.CreateElement("packageSourceCredentials")
- $doc.DocumentElement.AppendChild($creds) | Out-Null
-}
-
# Check for disabledPackageSources; we'll enable any darc-int ones we find there
$disabledSources = $doc.DocumentElement.SelectSingleNode("disabledPackageSources")
-if ($disabledSources -ne $null) {
+if ($null -ne $disabledSources) {
Write-Host "Checking for any darc-int disabled package sources in the disabledPackageSources node"
- EnablePrivatePackageSources -DisabledPackageSources $disabledSources
+ EnableInternalPackageSources -DisabledPackageSources $disabledSources
}
-$userName = "dn-bot"
-
-# Insert credential nodes for Maestro's private feeds
-InsertMaestroPrivateFeedCredentials -Sources $sources -Creds $creds -Username $userName -pwd $Password
+if ($Password) {
+ InsertMaestroInternalFeedCredentials -Sources $sources -pwd $Password
+}
# 3.1 uses a different feed url format so it's handled differently here
$dotnet31Source = $sources.SelectSingleNode("add[@key='dotnet3.1']")
-if ($dotnet31Source -ne $null) {
- AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v2" -Creds $creds -Username $userName -pwd $Password
- AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v2" -Creds $creds -Username $userName -pwd $Password
+if ($null -ne $dotnet31Source) {
+ AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v3/index.json" -pwd $Password
+ AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v3/index.json" -pwd $Password
}
$dotnetVersions = @('5','6','7','8')
@@ -158,10 +133,18 @@ $dotnetVersions = @('5','6','7','8')
foreach ($dotnetVersion in $dotnetVersions) {
$feedPrefix = "dotnet" + $dotnetVersion;
$dotnetSource = $sources.SelectSingleNode("add[@key='$feedPrefix']")
- if ($dotnetSource -ne $null) {
- AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal/nuget/v2" -Creds $creds -Username $userName -pwd $Password
- AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal-transport/nuget/v2" -Creds $creds -Username $userName -pwd $Password
+ if ($dotnetSource) {
+ AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedprefix-internal/nuget/v3/index.json" -pwd $Password
+ AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal-transport/nuget/v3/index.json" -pwd $Password
}
}
-$doc.Save($filename)
\ No newline at end of file
+$doc.Save($filename)
+
+# If any credentials were added or altered, update the VSS_NUGET_EXTERNAL_FEED_ENDPOINTS environment variable
+if ($null -ne $feedEndpoints) {
+ # ci is set to true so vso logging commands will be used.
+ $ci = $true
+ Write-PipelineSetVariable -Name 'VSS_NUGET_EXTERNAL_FEED_ENDPOINTS' -Value $($feedEndpoints | ConvertTo-Json) -IsMultiJobVariable $false
+ Write-PipelineSetVariable -Name 'NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED' -Value "False" -IsMultiJobVariable $false
+}
\ No newline at end of file
diff --git a/eng/common/SetupNugetSources.sh b/eng/common/SetupNugetSources.sh
index d387c7eac95e5..16c1e29ea3b79 100644
--- a/eng/common/SetupNugetSources.sh
+++ b/eng/common/SetupNugetSources.sh
@@ -1,28 +1,27 @@
#!/usr/bin/env bash
-# This file is a temporary workaround for internal builds to be able to restore from private AzDO feeds.
-# This file should be removed as part of this issue: https://github.com/dotnet/arcade/issues/4080
+# This script adds internal feeds required to build commits that depend on intenral package sources. For instance,
+# dotnet6-internal would be added automatically if dotnet6 was found in the nuget.config file. In addition also enables
+# disabled internal Maestro (darc-int*) feeds.
+#
+# Optionally, this script also adds a credential entry for each of the internal feeds if supplied.
#
-# What the script does is iterate over all package sources in the pointed NuGet.config and add a credential entry
-# under for each Maestro's managed private feed. Two additional credential
-# entries are also added for the two private static internal feeds: dotnet3-internal and dotnet3-internal-transport.
-#
-# This script needs to be called in every job that will restore packages and which the base repo has
-# private AzDO feeds in the NuGet.config.
-#
-# See example YAML call for this script below. Note the use of the variable `$(dn-bot-dnceng-artifact-feeds-rw)`
-# from the AzureDevOps-Artifact-Feeds-Pats variable group.
-#
-# Any disabledPackageSources entries which start with "darc-int" will be re-enabled as part of this script executing.
+# See example call for this script below.
#
# - task: Bash@3
-# displayName: Setup Private Feeds Credentials
+# displayName: Setup Internal Feeds
# inputs:
# filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh
-# arguments: $(Build.SourcesDirectory)/NuGet.config $Token
+# arguments: $(Build.SourcesDirectory)/NuGet.config
# condition: ne(variables['Agent.OS'], 'Windows_NT')
-# env:
-# Token: $(dn-bot-dnceng-artifact-feeds-rw)
+# - task: NuGetAuthenticate@1
+#
+# Note that the NuGetAuthenticate task should be called after SetupNugetSources.
+# This ensures that:
+# - Appropriate creds are set for the added internal feeds (if not supplied to the scrupt)
+# - The credential provider is installed.
+#
+# This logic is also abstracted into enable-internal-sources.yml.
ConfigFile=$1
CredToken=$2
@@ -48,11 +47,6 @@ if [ ! -f "$ConfigFile" ]; then
ExitWithExitCode 1
fi
-if [ -z "$CredToken" ]; then
- Write-PipelineTelemetryError -category 'Build' "Error: Eng/common/SetupNugetSources.sh returned a non-zero exit code. Please supply a valid PAT"
- ExitWithExitCode 1
-fi
-
if [[ `uname -s` == "Darwin" ]]; then
NL=$'\\\n'
TB=''
@@ -140,18 +134,20 @@ PackageSources+="$IFS"
PackageSources+=$(grep -oh '"darc-int-[^"]*"' $ConfigFile | tr -d '"')
IFS=$PrevIFS
-for FeedName in ${PackageSources[@]} ; do
- # Check if there is no existing credential for this FeedName
- grep -i "<$FeedName>" $ConfigFile
- if [ "$?" != "0" ]; then
- echo "Adding credentials for $FeedName."
+if [ "$CredToken" ]; then
+ for FeedName in ${PackageSources[@]} ; do
+ # Check if there is no existing credential for this FeedName
+ grep -i "<$FeedName>" $ConfigFile
+ if [ "$?" != "0" ]; then
+ echo "Adding credentials for $FeedName."
- PackageSourceCredentialsNodeFooter=" "
- NewCredential="${TB}${TB}<$FeedName>${NL} ${NL} ${NL}$FeedName>"
+ PackageSourceCredentialsNodeFooter=" "
+ NewCredential="${TB}${TB}<$FeedName>${NL} ${NL} ${NL}$FeedName>"
- sed -i.bak "s|$PackageSourceCredentialsNodeFooter|$NewCredential${NL}$PackageSourceCredentialsNodeFooter|" $ConfigFile
- fi
-done
+ sed -i.bak "s|$PackageSourceCredentialsNodeFooter|$NewCredential${NL}$PackageSourceCredentialsNodeFooter|" $ConfigFile
+ fi
+ done
+fi
# Re-enable any entries in disabledPackageSources where the feed name contains darc-int
grep -i "" $ConfigFile
diff --git a/eng/common/core-templates/job/job.yml b/eng/common/core-templates/job/job.yml
index dc3bd560a50e2..74872895d51cd 100644
--- a/eng/common/core-templates/job/job.yml
+++ b/eng/common/core-templates/job/job.yml
@@ -1,5 +1,5 @@
parameters:
-# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
+# Job schema parameters - https://learn.microsoft.com/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
cancelTimeoutInMinutes: ''
condition: ''
container: ''
@@ -83,7 +83,7 @@ jobs:
- name: EnableRichCodeNavigation
value: 'true'
# Retry signature validation up to three times, waiting 2 seconds between attempts.
- # See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures
+ # See https://learn.microsoft.com/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures
- name: NUGET_EXPERIMENTAL_CHAIN_BUILD_RETRY_POLICY
value: 3,2000
- ${{ each variable in parameters.variables }}:
@@ -200,29 +200,28 @@ jobs:
publishArtifacts: false
# Publish test results
- - ${{ if and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')) }}:
- - ${{ if eq(parameters.testResultsFormat, 'xunit') }}:
- - task: PublishTestResults@2
- displayName: Publish XUnit Test Results
- inputs:
- testResultsFormat: 'xUnit'
- testResultsFiles: '*.xml'
- searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
- testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit
- mergeTestResults: ${{ parameters.mergeTestResults }}
- continueOnError: true
- condition: always()
- - ${{ if eq(parameters.testResultsFormat, 'vstest') }}:
- - task: PublishTestResults@2
- displayName: Publish TRX Test Results
- inputs:
- testResultsFormat: 'VSTest'
- testResultsFiles: '*.trx'
- searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
- testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx
- mergeTestResults: ${{ parameters.mergeTestResults }}
- continueOnError: true
- condition: always()
+ - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}:
+ - task: PublishTestResults@2
+ displayName: Publish XUnit Test Results
+ inputs:
+ testResultsFormat: 'xUnit'
+ testResultsFiles: '*.xml'
+ searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
+ testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit
+ mergeTestResults: ${{ parameters.mergeTestResults }}
+ continueOnError: true
+ condition: always()
+ - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'vstest')) }}:
+ - task: PublishTestResults@2
+ displayName: Publish TRX Test Results
+ inputs:
+ testResultsFormat: 'VSTest'
+ testResultsFiles: '*.trx'
+ searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
+ testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx
+ mergeTestResults: ${{ parameters.mergeTestResults }}
+ continueOnError: true
+ condition: always()
# gather artifacts
- ${{ if ne(parameters.artifacts.publish, '') }}:
@@ -246,6 +245,8 @@ jobs:
SourceFolder: 'artifacts/log'
Contents: '**'
TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/log'
+ continueOnError: true
+ condition: always()
- ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}:
- task: CopyFiles@2
@@ -254,6 +255,8 @@ jobs:
SourceFolder: 'artifacts/log/$(_BuildConfig)'
Contents: '**'
TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'
+ continueOnError: true
+ condition: always()
- ${{ if eq(parameters.enableBuildRetry, 'true') }}:
- task: CopyFiles@2
displayName: Gather buildconfiguration for build retry
@@ -261,6 +264,7 @@ jobs:
SourceFolder: '$(Build.SourcesDirectory)/eng/common/BuildConfiguration'
Contents: '**'
TargetFolder: '$(Build.ArtifactStagingDirectory)/eng/common/BuildConfiguration'
-
+ continueOnError: true
+ condition: always()
- ${{ each step in parameters.artifactPublishSteps }}:
- ${{ step }}
diff --git a/eng/common/core-templates/job/onelocbuild.yml b/eng/common/core-templates/job/onelocbuild.yml
index 00feec8ebbc3a..84025d0bfe2ff 100644
--- a/eng/common/core-templates/job/onelocbuild.yml
+++ b/eng/common/core-templates/job/onelocbuild.yml
@@ -2,7 +2,7 @@ parameters:
# Optional: dependencies of the job
dependsOn: ''
- # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool
+ # Optional: A defined YAML pool - https://learn.microsoft.com/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
diff --git a/eng/common/core-templates/job/publish-build-assets.yml b/eng/common/core-templates/job/publish-build-assets.yml
index 8fe9299542c53..8b72fc5122b42 100644
--- a/eng/common/core-templates/job/publish-build-assets.yml
+++ b/eng/common/core-templates/job/publish-build-assets.yml
@@ -13,7 +13,7 @@ parameters:
# Optional: Include PublishBuildArtifacts task
enablePublishBuildArtifacts: false
- # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool
+ # Optional: A defined YAML pool - https://learn.microsoft.com/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool
pool: {}
# Optional: should run as a public build even in the internal project
diff --git a/eng/common/core-templates/job/source-build.yml b/eng/common/core-templates/job/source-build.yml
index c0ce4b3c86186..c4713c8b6ede8 100644
--- a/eng/common/core-templates/job/source-build.yml
+++ b/eng/common/core-templates/job/source-build.yml
@@ -33,6 +33,12 @@ parameters:
is1ESPipeline: ''
+ # If set to true and running on a non-public project,
+ # Internal nuget and blob storage locations will be enabled.
+ # This is not enabled by default because many repositories do not need internal sources
+ # and do not need to have the required service connections approved in the pipeline.
+ enableInternalSources: false
+
jobs:
- job: ${{ parameters.jobNamePrefix }}_${{ parameters.platform.name }}
displayName: Source-Build (${{ parameters.platform.name }})
@@ -74,6 +80,13 @@ jobs:
- ${{ if eq(parameters.is1ESPipeline, '') }}:
- 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error
+ - ${{ if eq(parameters.enableInternalSources, true) }}:
+ - template: /eng/common/core-templates/steps/enable-internal-sources.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ - template: /eng/common/core-templates/steps/enable-internal-runtimes.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
- template: /eng/common/core-templates/steps/source-build.yml
parameters:
is1ESPipeline: ${{ parameters.is1ESPipeline }}
diff --git a/eng/common/core-templates/jobs/codeql-build.yml b/eng/common/core-templates/jobs/codeql-build.yml
index f2144252cc65c..0ca1f8019ef08 100644
--- a/eng/common/core-templates/jobs/codeql-build.yml
+++ b/eng/common/core-templates/jobs/codeql-build.yml
@@ -1,7 +1,7 @@
parameters:
# See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md
continueOnError: false
- # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
+ # Required: A collection of jobs to run - https://learn.microsoft.com/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
jobs: []
# Optional: if specified, restore and use this version of Guardian instead of the default.
overrideGuardianVersion: ''
diff --git a/eng/common/core-templates/jobs/jobs.yml b/eng/common/core-templates/jobs/jobs.yml
index ea69be4341c62..a7e082b4ff989 100644
--- a/eng/common/core-templates/jobs/jobs.yml
+++ b/eng/common/core-templates/jobs/jobs.yml
@@ -21,7 +21,7 @@ parameters:
# Optional: Include toolset dependencies in the generated graph files
includeToolset: false
- # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
+ # Required: A collection of jobs to run - https://learn.microsoft.com/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
jobs: []
# Optional: Override automatically derived dependsOn value for "publish build assets" job
diff --git a/eng/common/core-templates/jobs/source-build.yml b/eng/common/core-templates/jobs/source-build.yml
index d8e5d00852268..a10ccfbee6de6 100644
--- a/eng/common/core-templates/jobs/source-build.yml
+++ b/eng/common/core-templates/jobs/source-build.yml
@@ -23,6 +23,12 @@ parameters:
is1ESPipeline: ''
+ # If set to true and running on a non-public project,
+ # Internal nuget and blob storage locations will be enabled.
+ # This is not enabled by default because many repositories do not need internal sources
+ # and do not need to have the required service connections approved in the pipeline.
+ enableInternalSources: false
+
jobs:
- ${{ if ne(parameters.allCompletedJobId, '') }}:
@@ -41,6 +47,7 @@ jobs:
is1ESPipeline: ${{ parameters.is1ESPipeline }}
jobNamePrefix: ${{ parameters.jobNamePrefix }}
platform: ${{ platform }}
+ enableInternalSources: ${{ parameters.enableInternalSources }}
- ${{ if eq(length(parameters.platforms), 0) }}:
- template: /eng/common/core-templates/job/source-build.yml
@@ -48,3 +55,4 @@ jobs:
is1ESPipeline: ${{ parameters.is1ESPipeline }}
jobNamePrefix: ${{ parameters.jobNamePrefix }}
platform: ${{ parameters.defaultManagedPlatform }}
+ enableInternalSources: ${{ parameters.enableInternalSources }}
diff --git a/eng/common/core-templates/steps/enable-internal-runtimes.yml b/eng/common/core-templates/steps/enable-internal-runtimes.yml
new file mode 100644
index 0000000000000..6bdbf62ac500f
--- /dev/null
+++ b/eng/common/core-templates/steps/enable-internal-runtimes.yml
@@ -0,0 +1,32 @@
+# Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64'
+# variable with the base64-encoded SAS token, by default
+
+parameters:
+- name: federatedServiceConnection
+ type: string
+ default: 'dotnetbuilds-internal-read'
+- name: outputVariableName
+ type: string
+ default: 'dotnetbuilds-internal-container-read-token-base64'
+- name: expiryInHours
+ type: number
+ default: 1
+- name: base64Encode
+ type: boolean
+ default: true
+- name: is1ESPipeline
+ type: boolean
+ default: false
+
+steps:
+- ${{ if ne(variables['System.TeamProject'], 'public') }}:
+ - template: /eng/common/core-templates/steps/get-delegation-sas.yml
+ parameters:
+ federatedServiceConnection: ${{ parameters.federatedServiceConnection }}
+ outputVariableName: ${{ parameters.outputVariableName }}
+ expiryInHours: ${{ parameters.expiryInHours }}
+ base64Encode: ${{ parameters.base64Encode }}
+ storageAccount: dotnetbuilds
+ container: internal
+ permissions: rl
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
\ No newline at end of file
diff --git a/eng/common/core-templates/steps/enable-internal-sources.yml b/eng/common/core-templates/steps/enable-internal-sources.yml
new file mode 100644
index 0000000000000..80deddafb1b64
--- /dev/null
+++ b/eng/common/core-templates/steps/enable-internal-sources.yml
@@ -0,0 +1,35 @@
+parameters:
+# This is the Azure federated service connection that we log into to get an access token.
+- name: nugetFederatedServiceConnection
+ type: string
+ default: 'dnceng-artifacts-feeds-read'
+- name: is1ESPipeline
+ type: boolean
+ default: false
+
+steps:
+- ${{ if ne(variables['System.TeamProject'], 'public') }}:
+ # If running on dnceng (internal project), just use the default behavior for NuGetAuthenticate.
+ # If running on DevDiv, NuGetAuthenticate is not really an option. It's scoped to a single feed, and we have many feeds that
+ # may be added. Instead, we'll use the traditional approach (add cred to nuget.config), but use an account token.
+ - ${{ if eq(variables['System.TeamProject'], 'internal') }}:
+ - task: PowerShell@2
+ displayName: Setup Internal Feeds
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1
+ arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config
+ - task: NuGetAuthenticate@1
+ - ${{ else }}:
+ - template: /eng/common/templates/steps/get-federated-access-token.yml
+ parameters:
+ federatedServiceConnection: ${{ parameters.nugetFederatedServiceConnection }}
+ outputVariableName: 'dnceng-artifacts-feeds-read-access-token'
+ - 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)
+ # 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).
+ - task: NuGetAuthenticate@1
diff --git a/eng/common/templates/steps/get-delegate-sas.yml b/eng/common/core-templates/steps/get-delegation-sas.yml
similarity index 96%
rename from eng/common/templates/steps/get-delegate-sas.yml
rename to eng/common/core-templates/steps/get-delegation-sas.yml
index c0e8f91317f07..d2901470a7f0b 100644
--- a/eng/common/templates/steps/get-delegate-sas.yml
+++ b/eng/common/core-templates/steps/get-delegation-sas.yml
@@ -16,6 +16,9 @@ parameters:
- name: permissions
type: string
default: 'rl'
+- name: is1ESPipeline
+ type: boolean
+ default: false
steps:
- task: AzureCLI@2
diff --git a/eng/common/core-templates/steps/get-federated-access-token.yml b/eng/common/core-templates/steps/get-federated-access-token.yml
new file mode 100644
index 0000000000000..c8c49cc0e8f0f
--- /dev/null
+++ b/eng/common/core-templates/steps/get-federated-access-token.yml
@@ -0,0 +1,28 @@
+parameters:
+- name: federatedServiceConnection
+ type: string
+- name: outputVariableName
+ type: string
+# Resource to get a token for. Common values include:
+# - '499b84ac-1321-427f-aa17-267ca6975798' for Azure DevOps
+# - 'https://storage.azure.com/' for storage
+# Defaults to Azure DevOps
+- name: resource
+ type: string
+ default: '499b84ac-1321-427f-aa17-267ca6975798'
+
+steps:
+- task: AzureCLI@2
+ displayName: 'Getting federated access token for feeds'
+ inputs:
+ azureSubscription: ${{ parameters.federatedServiceConnection }}
+ scriptType: 'pscore'
+ scriptLocation: 'inlineScript'
+ inlineScript: |
+ $accessToken = az account get-access-token --query accessToken --resource ${{ parameters.resource }} --output tsv
+ if ($LASTEXITCODE -ne 0) {
+ Write-Error "Failed to get access token for resource '${{ parameters.resource }}'"
+ exit 1
+ }
+ Write-Host "Setting '${{ parameters.outputVariableName }}' with the access token value"
+ Write-Host "##vso[task.setvariable variable=${{ parameters.outputVariableName }};issecret=true]$accessToken"
\ No newline at end of file
diff --git a/eng/common/core-templates/steps/source-build.yml b/eng/common/core-templates/steps/source-build.yml
index bdd725b496f91..16c778d92cb51 100644
--- a/eng/common/core-templates/steps/source-build.yml
+++ b/eng/common/core-templates/steps/source-build.yml
@@ -19,18 +19,10 @@ steps:
set -x
df -h
- # If building on the internal project, the artifact feeds variable may be available (usually only if needed)
- # In that case, call the feed setup script to add internal feeds corresponding to public ones.
- # In addition, add an msbuild argument to copy the WIP from the repo to the target build location.
- # This is because SetupNuGetSources.sh will alter the current NuGet.config file, and we need to preserve those
- # changes.
+ # If file changes are detected, set CopyWipIntoInnerSourceBuildRepo to copy the WIP changes into the inner source build repo.
internalRestoreArgs=
- if [ '$(dn-bot-dnceng-artifact-feeds-rw)' != '$''(dn-bot-dnceng-artifact-feeds-rw)' ]; then
- # Temporarily work around https://github.com/dotnet/arcade/issues/7709
- chmod +x $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh
- $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh $(Build.SourcesDirectory)/NuGet.config $(dn-bot-dnceng-artifact-feeds-rw)
+ if ! git diff --quiet; then
internalRestoreArgs='/p:CopyWipIntoInnerSourceBuildRepo=true'
-
# The 'Copy WIP' feature of source build uses git stash to apply changes from the original repo.
# This only works if there is a username/email configured, which won't be the case in most CI runs.
git config --get user.email
@@ -123,6 +115,7 @@ steps:
artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt)
continueOnError: true
condition: succeededOrFailed()
+ sbomEnabled: false # we don't need SBOM for logs
# Manually inject component detection so that we can ignore the source build upstream cache, which contains
# a nupkg cache of input packages (a local feed).
diff --git a/eng/common/cross/armv6/sources.list.bookworm b/eng/common/cross/armv6/sources.list.bookworm
new file mode 100644
index 0000000000000..10161135265cf
--- /dev/null
+++ b/eng/common/cross/armv6/sources.list.bookworm
@@ -0,0 +1,2 @@
+deb http://raspbian.raspberrypi.org/raspbian/ bookworm main contrib non-free rpi
+deb-src http://raspbian.raspberrypi.org/raspbian/ bookworm main contrib non-free rpi
diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh
index a8e35df7cee14..7455dcb6af4d1 100755
--- a/eng/common/cross/build-rootfs.sh
+++ b/eng/common/cross/build-rootfs.sh
@@ -314,6 +314,13 @@ while :; do
bullseye) # Debian 11
__CodeName=bullseye
+ if [[ -z "$__UbuntuRepo" ]]; then
+ __UbuntuRepo="http://ftp.debian.org/debian/"
+ fi
+ ;;
+ bookworm) # Debian 12
+ __CodeName=bookworm
+
if [[ -z "$__UbuntuRepo" ]]; then
__UbuntuRepo="http://ftp.debian.org/debian/"
fi
diff --git a/eng/common/cross/tizen-fetch.sh b/eng/common/cross/tizen-fetch.sh
index c15c5066950d1..28936ceef3a71 100755
--- a/eng/common/cross/tizen-fetch.sh
+++ b/eng/common/cross/tizen-fetch.sh
@@ -7,7 +7,7 @@ fi
Log()
{
- if [ $VERBOSE -ge $1 ]; then
+ if [ $VERBOSE -ge 1 ]; then
echo ${@:2}
fi
}
diff --git a/eng/common/dotnet-install.sh b/eng/common/dotnet-install.sh
index 7e69e3a9e24a7..a2fba4703806e 100755
--- a/eng/common/dotnet-install.sh
+++ b/eng/common/dotnet-install.sh
@@ -82,7 +82,7 @@ if [[ $architecture != "" ]] && [[ $architecture != $buildarch ]]; then
dotnetRoot="$dotnetRoot/$architecture"
fi
-InstallDotNet $dotnetRoot $version "$architecture" $runtime true $runtimeSourceFeed $runtimeSourceFeedKey || {
+InstallDotNet "$dotnetRoot" $version "$architecture" $runtime true $runtimeSourceFeed $runtimeSourceFeedKey || {
local exit_code=$?
Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "dotnet-install.sh failed (exit code '$exit_code')." >&2
ExitWithExitCode $exit_code
diff --git a/eng/common/template-guidance.md b/eng/common/template-guidance.md
index c114bc28dcb95..48954b48b8dae 100644
--- a/eng/common/template-guidance.md
+++ b/eng/common/template-guidance.md
@@ -20,7 +20,7 @@ The `templateIs1ESManaged` is available on most templates and affects which of t
## Multiple outputs
-1ES pipeline templates impose a policy where every publish artifact execution results in additional security scans being injected into your pipeline. When using `templates-official/jobs/jobs.yml`, Arcade reduces the number of additional security injections by gathering all publishing outputs into the [Build.ArtifactStagingDirectory](https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services), and utilizing the [outputParentDirectory](https://eng.ms/docs/cloud-ai-platform/devdiv/one-engineering-system-1es/1es-docs/1es-pipeline-templates/features/outputs#multiple-outputs) feature of 1ES pipeline templates. When implementing your pipeline, if you ensure publish artifacts are located in the `$(Build.ArtifactStagingDirectory)`, and utilize the 1ES provided template context, then you can reduce the number of security scans for your pipeline.
+1ES pipeline templates impose a policy where every publish artifact execution results in additional security scans being injected into your pipeline. When using `templates-official/jobs/jobs.yml`, Arcade reduces the number of additional security injections by gathering all publishing outputs into the [Build.ArtifactStagingDirectory](https://learn.microsoft.com/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services), and utilizing the [outputParentDirectory](https://eng.ms/docs/cloud-ai-platform/devdiv/one-engineering-system-1es/1es-docs/1es-pipeline-templates/features/outputs#multiple-outputs) feature of 1ES pipeline templates. When implementing your pipeline, if you ensure publish artifacts are located in the `$(Build.ArtifactStagingDirectory)`, and utilize the 1ES provided template context, then you can reduce the number of security scans for your pipeline.
Example:
``` yaml
diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml
index 4724e9aaa8091..0c2928d5c799e 100644
--- a/eng/common/templates-official/job/job.yml
+++ b/eng/common/templates-official/job/job.yml
@@ -23,6 +23,7 @@ jobs:
displayName: 'Publish logs'
continueOnError: true
condition: always()
+ sbomEnabled: false # we don't need SBOM for logs
- ${{ if eq(parameters.enablePublishBuildArtifacts, true) }}:
- output: buildArtifacts
@@ -32,13 +33,15 @@ jobs:
ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }}
continueOnError: true
condition: always()
+ sbomEnabled: false # we don't need SBOM for logs
- ${{ if eq(parameters.enableBuildRetry, 'true') }}:
- output: pipelineArtifact
targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/eng/common/BuildConfiguration'
artifactName: 'BuildConfiguration'
displayName: 'Publish build retry configuration'
- continueOnError: true
+ continueOnError: true
+ sbomEnabled: false # we don't need SBOM for BuildConfiguration
- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}:
- output: pipelineArtifact
diff --git a/eng/common/templates-official/steps/enable-internal-runtimes.yml b/eng/common/templates-official/steps/enable-internal-runtimes.yml
new file mode 100644
index 0000000000000..f9dd238c6cd54
--- /dev/null
+++ b/eng/common/templates-official/steps/enable-internal-runtimes.yml
@@ -0,0 +1,9 @@
+# Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64'
+# variable with the base64-encoded SAS token, by default
+steps:
+- template: /eng/common/core-templates/steps/enable-internal-runtimes.yml
+ parameters:
+ is1ESPipeline: true
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/steps/enable-internal-sources.yml b/eng/common/templates-official/steps/enable-internal-sources.yml
new file mode 100644
index 0000000000000..e6d57182284df
--- /dev/null
+++ b/eng/common/templates-official/steps/enable-internal-sources.yml
@@ -0,0 +1,7 @@
+steps:
+- template: /eng/common/core-templates/steps/enable-internal-sources.yml
+ parameters:
+ is1ESPipeline: true
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
\ No newline at end of file
diff --git a/eng/common/templates-official/steps/get-delegation-sas.yml b/eng/common/templates-official/steps/get-delegation-sas.yml
new file mode 100644
index 0000000000000..c5a9c1f8275c5
--- /dev/null
+++ b/eng/common/templates-official/steps/get-delegation-sas.yml
@@ -0,0 +1,7 @@
+steps:
+- template: /eng/common/core-templates/steps/get-delegation-sas.yml
+ parameters:
+ is1ESPipeline: true
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/steps/get-federated-access-token.yml b/eng/common/templates-official/steps/get-federated-access-token.yml
new file mode 100644
index 0000000000000..c8dcf6b813920
--- /dev/null
+++ b/eng/common/templates-official/steps/get-federated-access-token.yml
@@ -0,0 +1,7 @@
+steps:
+- template: /eng/common/core-templates/steps/get-federated-access-token.yml
+ parameters:
+ is1ESPipeline: true
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
\ No newline at end of file
diff --git a/eng/common/templates-official/steps/publish-pipeline-artifacts.yml b/eng/common/templates-official/steps/publish-pipeline-artifacts.yml
index d71eb0c743986..172f9f0fdc970 100644
--- a/eng/common/templates-official/steps/publish-pipeline-artifacts.yml
+++ b/eng/common/templates-official/steps/publish-pipeline-artifacts.yml
@@ -23,4 +23,6 @@ steps:
${{ if parameters.args.artifactName }}:
artifactName: ${{ parameters.args.artifactName }}
${{ if parameters.args.properties }}:
- properties: ${{ parameters.args.properties }}
\ No newline at end of file
+ properties: ${{ parameters.args.properties }}
+ ${{ if parameters.args.sbomEnabled }}:
+ sbomEnabled: ${{ parameters.args.sbomEnabled }}
diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml
index 1cf9a6d48127b..5920952c5ba69 100644
--- a/eng/common/templates/job/job.yml
+++ b/eng/common/templates/job/job.yml
@@ -37,6 +37,7 @@ jobs:
displayName: 'Publish logs'
continueOnError: true
condition: always()
+ sbomEnabled: false # we don't need SBOM for logs
- ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}:
- template: /eng/common/core-templates/steps/publish-build-artifacts.yml
@@ -59,3 +60,4 @@ jobs:
artifactName: 'BuildConfiguration'
displayName: 'Publish build retry configuration'
continueOnError: true
+ sbomEnabled: false # we don't need SBOM for BuildConfiguration
diff --git a/eng/common/templates/steps/enable-internal-runtimes.yml b/eng/common/templates/steps/enable-internal-runtimes.yml
new file mode 100644
index 0000000000000..b21a8038cc1cb
--- /dev/null
+++ b/eng/common/templates/steps/enable-internal-runtimes.yml
@@ -0,0 +1,10 @@
+# Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64'
+# variable with the base64-encoded SAS token, by default
+
+steps:
+- template: /eng/common/core-templates/steps/enable-internal-runtimes.yml
+ parameters:
+ is1ESPipeline: false
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/steps/enable-internal-sources.yml b/eng/common/templates/steps/enable-internal-sources.yml
new file mode 100644
index 0000000000000..5f87e9abb8aaa
--- /dev/null
+++ b/eng/common/templates/steps/enable-internal-sources.yml
@@ -0,0 +1,7 @@
+steps:
+- template: /eng/common/core-templates/steps/enable-internal-sources.yml
+ parameters:
+ is1ESPipeline: false
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
\ No newline at end of file
diff --git a/eng/common/templates/steps/get-delegation-sas.yml b/eng/common/templates/steps/get-delegation-sas.yml
new file mode 100644
index 0000000000000..83760c9798e36
--- /dev/null
+++ b/eng/common/templates/steps/get-delegation-sas.yml
@@ -0,0 +1,7 @@
+steps:
+- template: /eng/common/core-templates/steps/get-delegation-sas.yml
+ parameters:
+ is1ESPipeline: false
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/steps/get-federated-access-token.yml b/eng/common/templates/steps/get-federated-access-token.yml
new file mode 100644
index 0000000000000..31e151d9d9e79
--- /dev/null
+++ b/eng/common/templates/steps/get-federated-access-token.yml
@@ -0,0 +1,7 @@
+steps:
+- template: /eng/common/core-templates/steps/get-federated-access-token.yml
+ parameters:
+ is1ESPipeline: false
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
\ No newline at end of file
diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1
index 0febe696dbdbc..204cb54af051b 100644
--- a/eng/common/tools.ps1
+++ b/eng/common/tools.ps1
@@ -520,7 +520,7 @@ function InitializeXCopyMSBuild([string]$packageVersion, [bool]$install) {
# Two part minimal VS version, e.g. "15.9", "16.0", etc.
# "components": ["componentId1", "componentId2", ...]
# Array of ids of workload components that must be available in the VS instance.
-# See e.g. https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-enterprise?view=vs-2017
+# See e.g. https://learn.microsoft.com/visualstudio/install/workload-component-id-vs-enterprise?view=vs-2017
#
# Returns JSON describing the located VS instance (same format as returned by vswhere),
# or $null if no instance meeting the requirements is found on the machine.
diff --git a/eng/common/tools.sh b/eng/common/tools.sh
index db64e298ff631..a4f5d1b7761b4 100755
--- a/eng/common/tools.sh
+++ b/eng/common/tools.sh
@@ -438,7 +438,7 @@ function StopProcesses {
}
function MSBuild {
- local args=$@
+ local args=( "$@" )
if [[ "$pipelines_log" == true ]]; then
InitializeBuildTool
InitializeToolset
@@ -473,7 +473,7 @@ function MSBuild {
args+=( "-logger:$selectedPath" )
fi
- MSBuild-Core ${args[@]}
+ MSBuild-Core "${args[@]}"
}
function MSBuild-Core {
diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake
index ea2ace1672750..8decaa84fe9ad 100644
--- a/eng/native/configurecompiler.cmake
+++ b/eng/native/configurecompiler.cmake
@@ -520,7 +520,7 @@ if (CLR_CMAKE_HOST_UNIX)
# Disable frame pointer optimizations so profilers can get better call stacks
add_compile_options(-fno-omit-frame-pointer)
- # The -fms-extensions enable the stuff like __if_exists, __declspec(uuid()), etc.
+ # The -fms-extensions enable the stuff like __declspec(uuid()), etc.
add_compile_options(-fms-extensions)
#-fms-compatibility Enable full Microsoft Visual C++ compatibility
#-fms-extensions Accept some non-standard constructs supported by the Microsoft compiler
diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml
index 13da1c03fbaf4..1fe318e984fa8 100644
--- a/eng/pipelines/common/global-build-job.yml
+++ b/eng/pipelines/common/global-build-job.yml
@@ -187,6 +187,10 @@ jobs:
arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token
env:
Token: $(dn-bot-dnceng-artifact-feeds-rw)
+ # Run the NuGetAuthenticate task after the internal feeds are added to the nuget.config
+ # This ensures that creds are set appropriately for all feeds in the config, and that the
+ # credential provider is installed.
+ - task: NuGetAuthenticate@1
- ${{ each monoCrossAOTTargetOS in parameters.monoCrossAOTTargetOS }}:
- task: DownloadPipelineArtifact@2
diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml
index 49f9ba6e3f240..23370eabe21a6 100644
--- a/eng/pipelines/common/platform-matrix.yml
+++ b/eng/pipelines/common/platform-matrix.yml
@@ -571,7 +571,7 @@ jobs:
targetRid: android-x64
platform: android_x64
shouldContinueOnError: ${{ parameters.shouldContinueOnError }}
- container: linux_bionic
+ container: android
jobParameters:
runtimeFlavor: mono
buildConfig: ${{ parameters.buildConfig }}
@@ -611,7 +611,7 @@ jobs:
targetRid: android-x86
platform: android_x86
shouldContinueOnError: ${{ parameters.shouldContinueOnError }}
- container: linux_bionic
+ container: android
jobParameters:
runtimeFlavor: mono
buildConfig: ${{ parameters.buildConfig }}
@@ -631,7 +631,7 @@ jobs:
targetRid: android-arm
platform: android_arm
shouldContinueOnError: ${{ parameters.shouldContinueOnError }}
- container: linux_bionic
+ container: android
jobParameters:
runtimeFlavor: mono
buildConfig: ${{ parameters.buildConfig }}
@@ -651,7 +651,7 @@ jobs:
targetRid: android-arm64
platform: android_arm64
shouldContinueOnError: ${{ parameters.shouldContinueOnError }}
- container: linux_bionic
+ container: android
jobParameters:
runtimeFlavor: mono
buildConfig: ${{ parameters.buildConfig }}
diff --git a/eng/pipelines/common/templates/pipeline-with-resources.yml b/eng/pipelines/common/templates/pipeline-with-resources.yml
index bf668d6441fe6..ffeafcdde7d2f 100644
--- a/eng/pipelines/common/templates/pipeline-with-resources.yml
+++ b/eng/pipelines/common/templates/pipeline-with-resources.yml
@@ -47,12 +47,16 @@ extends:
ROOTFS_DIR: /crossrootfs/arm64
# This container contains all required toolsets to build for Android and for Linux with bionic libc.
+ android:
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-android-amd64-net9.0
+
+ # This container contains all required toolsets to build for Android and for Linux with bionic libc and a special layout of OpenSSL.
linux_bionic:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-android-amd64
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-android-openssl-net9.0
# This container contains all required toolsets to build for Android as well as tooling to build docker images.
android_docker:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-android-docker
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-android-docker-net9.0
linux_x64:
image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-amd64-net9.0
@@ -84,12 +88,12 @@ extends:
image: mcr.microsoft.com/dotnet-buildtools/prereqs:almalinux-8-source-build
linux_s390x:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-s390x
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-s390x-net9.0
env:
ROOTFS_DIR: /crossrootfs/s390x
linux_ppc64le:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-ppc64le
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-ppc64le-net9.0
env:
ROOTFS_DIR: /crossrootfs/ppc64le
@@ -105,17 +109,17 @@ extends:
image: mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8
browser_wasm:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-webassembly
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-webassembly-amd64-net9.0
env:
ROOTFS_DIR: /crossrootfs/x64
wasi_wasm:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-webassembly
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-webassembly-amd64-net9.0
env:
ROOTFS_DIR: /crossrootfs/x64
freebsd_x64:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-amd64-freebsd-13
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-freebsd-13-net9.0
env:
ROOTFS_DIR: /crossrootfs/x64
@@ -128,4 +132,4 @@ extends:
image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-debpkg
rpmpkg:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-fpm
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-fpm-net9.0
diff --git a/eng/pipelines/common/templates/runtimes/build-test-job.yml b/eng/pipelines/common/templates/runtimes/build-test-job.yml
index c86e4e04f1116..bbc9f854801ff 100644
--- a/eng/pipelines/common/templates/runtimes/build-test-job.yml
+++ b/eng/pipelines/common/templates/runtimes/build-test-job.yml
@@ -44,7 +44,7 @@ jobs:
displayName: '${{ parameters.runtimeFlavor }} Common Pri1 Test Build AnyOS AnyCPU ${{ parameters.buildConfig }}'
# Since the condition is being altered, merge the default with the additional conditions.
- # See https://docs.microsoft.com/azure/devops/pipelines/process/conditions
+ # See https://learn.microsoft.com/azure/devops/pipelines/process/conditions
condition: and(succeeded(), ${{ parameters.condition }})
${{ if ne(parameters.dependsOn[0], '') }}:
diff --git a/eng/pipelines/common/templates/template1es.yml b/eng/pipelines/common/templates/template1es.yml
index 0964295750d25..e629a74646e59 100644
--- a/eng/pipelines/common/templates/template1es.yml
+++ b/eng/pipelines/common/templates/template1es.yml
@@ -15,7 +15,7 @@ resources:
- repository: 1ESPipelineTemplates
type: git
name: 1ESPipelineTemplates/1ESPipelineTemplates
- ref: refs/tags/release-2024-05-13-1
+ ref: refs/tags/release
extends:
template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates
diff --git a/eng/pipelines/coreclr/templates/run-performance-job.yml b/eng/pipelines/coreclr/templates/run-performance-job.yml
index 2b61558e2fc97..b99646881eb87 100644
--- a/eng/pipelines/coreclr/templates/run-performance-job.yml
+++ b/eng/pipelines/coreclr/templates/run-performance-job.yml
@@ -86,7 +86,7 @@ jobs:
${V8_ENGINE_PATH} -e 'console.log(`V8 version: ${this.version()}`)'
- ${{ if ne(parameters.runtimeType, 'wasm') }}:
- HelixPreCommandsWasmOnLinux: echo
- - HelixPreCommandStemWindows: 'set ORIGPYPATH=%PYTHONPATH%;py -m pip install -U pip;py -3 -m venv %HELIX_WORKITEM_PAYLOAD%\.venv;call %HELIX_WORKITEM_PAYLOAD%\.venv\Scripts\activate.bat;set PYTHONPATH=;py -3 -m pip install -U pip;py -3 -m pip install urllib3==1.26.15;py -3 -m pip install azure.storage.blob==12.0.0;py -3 -m pip install azure.storage.queue==12.0.0;set "PERFLAB_UPLOAD_TOKEN=$(HelixPerfUploadTokenValue)"'
+ - HelixPreCommandStemWindows: 'set ORIGPYPATH=%PYTHONPATH%;py -m pip install -U pip;py -3 -m venv %HELIX_WORKITEM_PAYLOAD%\.venv;call %HELIX_WORKITEM_PAYLOAD%\.venv\Scripts\activate.bat;set PYTHONPATH=;py -3 -m pip install -U pip;py -3 -m pip install urllib3==1.26.15;py -3 -m pip install azure.storage.blob==12.0.0;py -3 -m pip install azure.storage.queue==12.0.0;py -3 -m pip install azure.identity==1.16.0;set "PERFLAB_UPLOAD_TOKEN=$(HelixPerfUploadTokenValue)"'
- HelixPreCommandStemLinux: >-
export ORIGPYPATH=$PYTHONPATH
export CRYPTOGRAPHY_ALLOW_OPENSSL_102=true;
@@ -104,13 +104,14 @@ jobs:
pip3 install urllib3==1.26.15 &&
pip3 install --user azure.storage.blob==12.0.0 &&
pip3 install --user azure.storage.queue==12.0.0 &&
+ pip3 install --user azure.identity==1.16.0 &&
sudo apt-get update &&
sudo apt -y install curl dirmngr apt-transport-https lsb-release ca-certificates &&
$(HelixPreCommandsWasmOnLinux) &&
export PERFLAB_UPLOAD_TOKEN="$(HelixPerfUploadTokenValue)"
|| export PERF_PREREQS_INSTALL_FAILED=1;
test "x$PERF_PREREQS_INSTALL_FAILED" = "x1" && echo "** Error: Failed to install prerequites **"
- - HelixPreCommandStemMusl: 'ulimit -n 4096;export ORIGPYPATH=$PYTHONPATH;sudo apk add icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib cargo;sudo apk add libgdiplus --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing; python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/bin/activate;export PYTHONPATH=;python3 -m pip install -U pip;pip3 install urllib3==1.26.15;pip3 install azure.storage.blob==12.7.1;pip3 install azure.storage.queue==12.1.5;export PERFLAB_UPLOAD_TOKEN="$(HelixPerfUploadTokenValue)"'
+ - HelixPreCommandStemMusl: 'ulimit -n 4096;export ORIGPYPATH=$PYTHONPATH;sudo apk add icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib cargo;sudo apk add libgdiplus --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing; python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/bin/activate;export PYTHONPATH=;python3 -m pip install -U pip;pip3 install urllib3==1.26.15;pip3 install azure.storage.blob==12.7.1;pip3 install azure.storage.queue==12.1.5;pip3 install azure.identity==1.16.0;export PERFLAB_UPLOAD_TOKEN="$(HelixPerfUploadTokenValue)"'
- ExtraMSBuildLogsWindows: 'set MSBUILDDEBUGCOMM=1;set "MSBUILDDEBUGPATH=%HELIX_WORKITEM_UPLOAD_ROOT%"'
- ExtraMSBuildLogsLinux: 'export MSBUILDDEBUGCOMM=1;export "MSBUILDDEBUGPATH=$HELIX_WORKITEM_UPLOAD_ROOT"'
- HelixPreCommand: ''
diff --git a/eng/pipelines/coreclr/templates/run-scenarios-job.yml b/eng/pipelines/coreclr/templates/run-scenarios-job.yml
index 78db1ae8cbd09..c2cf7ad7fe642 100644
--- a/eng/pipelines/coreclr/templates/run-scenarios-job.yml
+++ b/eng/pipelines/coreclr/templates/run-scenarios-job.yml
@@ -60,16 +60,16 @@ jobs:
- SharedHelixPreCommands: 'chmod +x $HELIX_WORKITEM_PAYLOAD/machine-setup.sh;. $HELIX_WORKITEM_PAYLOAD/machine-setup.sh;export PYTHONPATH=$HELIX_WORKITEM_PAYLOAD/scripts:$HELIX_WORKITEM_PAYLOAD'
- ${{ if eq(parameters.osGroup, 'windows') }}:
- - HelixPreCommandWindows: 'set ORIGPYPATH=%PYTHONPATH%;py -3 -m venv %HELIX_WORKITEM_PAYLOAD%\.venv;call %HELIX_WORKITEM_PAYLOAD%\.venv\Scripts\activate.bat;set PYTHONPATH=;py -3 -m pip install -U pip;py -3 -m pip install --user azure.storage.blob==12.0.0;py -3 -m pip install --user azure.storage.queue==12.0.0;py -3 -m pip install --user urllib3==1.26.15;set "PERFLAB_UPLOAD_TOKEN=$(PerfCommandUploadToken)"'
+ - HelixPreCommandWindows: 'set ORIGPYPATH=%PYTHONPATH%;py -3 -m venv %HELIX_WORKITEM_PAYLOAD%\.venv;call %HELIX_WORKITEM_PAYLOAD%\.venv\Scripts\activate.bat;set PYTHONPATH=;py -3 -m pip install -U pip;py -3 -m pip install --user azure.storage.blob==12.0.0;py -3 -m pip install --user azure.storage.queue==12.0.0;py -3 -m pip install --user urllib3==1.26.15;py -3 -m pip install --user azure.identity==1.16.0;set "PERFLAB_UPLOAD_TOKEN=$(PerfCommandUploadToken)"'
- HelixPostCommandsWindows: 'set PYTHONPATH=%ORIGPYPATH%'
- ${{ if and(ne(parameters.osGroup, 'windows'), ne(parameters.osGroup, 'osx'), ne(parameters.osSubGroup, '_musl')) }}:
- - HelixPreCommandLinux: 'export ORIGPYPATH=$PYTHONPATH;export CRYPTOGRAPHY_ALLOW_OPENSSL_102=true;sudo apt-get -y install python3-venv;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/bin/activate;export PYTHONPATH=;python3 -m pip install -U pip;pip3 install --user azure.storage.blob==12.0.0;pip3 install --user azure.storage.queue==12.0.0;pip3 install --user urllib3==1.26.15;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"'
+ - HelixPreCommandLinux: 'export ORIGPYPATH=$PYTHONPATH;export CRYPTOGRAPHY_ALLOW_OPENSSL_102=true;sudo apt-get -y install python3-venv;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/bin/activate;export PYTHONPATH=;python3 -m pip install -U pip;pip3 install --user azure.storage.blob==12.0.0;pip3 install --user azure.storage.queue==12.0.0;pip3 install --user azure.identity==1.16.0;pip3 install --user urllib3==1.26.15;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"'
- HelixPostCommandsLinux: 'export PYTHONPATH=$ORIGPYPATH'
- ${{ if and(ne(parameters.osGroup, 'windows'), ne(parameters.osGroup, 'osx'), eq(parameters.osSubGroup, '_musl')) }}:
- - HelixPreCommandMusl: 'ulimit -n 4096;export ORIGPYPATH=$PYTHONPATH;sudo apk add py3-virtualenv;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/bin/activate;export PYTHONPATH=;python3 -m pip install -U pip;pip3 install --user azure.storage.blob==12.0.0;pip3 install --user azure.storage.queue==12.0.0;pip3 install --user urllib3==1.26.15;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"'
+ - HelixPreCommandMusl: 'ulimit -n 4096;export ORIGPYPATH=$PYTHONPATH;sudo apk add py3-virtualenv;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/bin/activate;export PYTHONPATH=;python3 -m pip install -U pip;pip3 install --user azure.storage.blob==12.0.0;pip3 install --user azure.storage.queue==12.0.0;pip3 install --user azure.identity==1.16.0;pip3 install --user urllib3==1.26.15;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"'
- HelixPostCommandsMusl: 'export PYTHONPATH=$ORIGPYPATH'
- ${{ if eq(parameters.osGroup, 'osx') }}:
- - HelixPreCommandOSX: 'export ORIGPYPATH=$PYTHONPATH;export CRYPTOGRAPHY_ALLOW_OPENSSL_102=true;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/bin/activate;export PYTHONPATH=;python3 -m pip install -U pip;pip3 install azure.storage.blob==12.0.0;pip3 install azure.storage.queue==12.0.0;pip3 install urllib3==1.26.15;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"'
+ - HelixPreCommandOSX: 'export ORIGPYPATH=$PYTHONPATH;export CRYPTOGRAPHY_ALLOW_OPENSSL_102=true;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/bin/activate;export PYTHONPATH=;python3 -m pip install -U pip;pip3 install azure.storage.blob==12.0.0;pip3 install azure.storage.queue==12.0.0;pip3 install azure.identity==1.16.0;pip3 install urllib3==1.26.15;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"'
- HelixPostCommandOSX: 'export PYTHONPATH=$ORIGPYPATH'
# extra private job settings
diff --git a/eng/pipelines/libraries/run-test-job.yml b/eng/pipelines/libraries/run-test-job.yml
index bc3697359f044..82017494a4bb5 100644
--- a/eng/pipelines/libraries/run-test-job.yml
+++ b/eng/pipelines/libraries/run-test-job.yml
@@ -104,6 +104,10 @@ jobs:
arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token
env:
Token: $(dn-bot-dnceng-artifact-feeds-rw)
+ # Run the NuGetAuthenticate task after the internal feeds are added to the nuget.config
+ # This ensures that creds are set appropriately for all feeds in the config, and that the
+ # credential provider is installed.
+ - task: NuGetAuthenticate@1
- ${{ if in(parameters.osGroup, 'osx', 'maccatalyst', 'ios', 'iossimulator', 'tvos', 'tvossimulator') }}:
- script: $(Build.SourcesDirectory)/eng/install-native-dependencies.sh ${{ parameters.osGroup }}
diff --git a/eng/testing/debug-dump-template.md b/eng/testing/debug-dump-template.md
index c8759600430f0..daf765c0c293b 100644
--- a/eng/testing/debug-dump-template.md
+++ b/eng/testing/debug-dump-template.md
@@ -41,7 +41,7 @@ You can read the rest of the document for information purposes (there is useful
# Install SOS debugging extension
-Now use the [dotnet-sos global tool](https://docs.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-sos) to install the SOS debugging extension.
+Now use the [dotnet-sos global tool](https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-sos) to install the SOS debugging extension.
```cmd
dotnet tool install --global dotnet-sos
dotnet tool update --global dotnet-sos
@@ -61,7 +61,7 @@ dotnet sos install --architecture x64
## ... and you want to debug with WinDbg
-Install or update WinDbg if necessary ([external](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-download-tools), [internal](https://osgwiki.com/wiki/Installing_WinDbg)). If you don't have a recent WinDbg you may have to do `.update sos`.
+Install or update WinDbg if necessary ([external](https://learn.microsoft.com/windows-hardware/drivers/debugger/debugger-download-tools), [internal](https://osgwiki.com/wiki/Installing_WinDbg)). If you don't have a recent WinDbg you may have to do `.update sos`.
Open WinDbg and open the dump with `File>Open Dump`.
```
@@ -81,7 +81,7 @@ Currently this is not possible because mscordbi.dll is not signed.
## ... and you want to debug with dotnet-dump
-Install the [dotnet-dump global tool](https://docs.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-dump).
+Install the [dotnet-dump global tool](https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-dump).
```cmd
dotnet tool install --global dotnet-dump
dotnet tool update --global dotnet-dump
@@ -129,7 +129,7 @@ loadsymbols
## ... and you want to debug with dotnet-dump
-Install the [dotnet-dump global tool](https://docs.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-dump).
+Install the [dotnet-dump global tool](https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-dump).
```sh
dotnet tool install --global dotnet-dump
dotnet tool update --global dotnet-dump
diff --git a/eng/testing/scenarios/BuildWasmAppsJobsList.txt b/eng/testing/scenarios/BuildWasmAppsJobsList.txt
index 11bfdab2c7414..58c5621f45240 100644
--- a/eng/testing/scenarios/BuildWasmAppsJobsList.txt
+++ b/eng/testing/scenarios/BuildWasmAppsJobsList.txt
@@ -46,4 +46,5 @@ Wasm.Build.Tests.WasmSIMDTests
Wasm.Build.Tests.WasmTemplateTests
Wasm.Build.Tests.WorkloadTests
Wasm.Build.Tests.MT.Blazor.SimpleMultiThreadedTests
-Wasm.Build.Tests.TestAppScenarios.DebugLevelTests
+Wasm.Build.Tests.TestAppScenarios.WasmSdkDebugLevelTests
+Wasm.Build.Tests.TestAppScenarios.WasmAppBuilderDebugLevelTests
diff --git a/global.json b/global.json
index 1d941dfd8c893..62754257d5c7b 100644
--- a/global.json
+++ b/global.json
@@ -8,9 +8,9 @@
"dotnet": "9.0.100-preview.4.24267.66"
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24272.5",
- "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24272.5",
- "Microsoft.DotNet.SharedFramework.Sdk": "9.0.0-beta.24272.5",
+ "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24281.1",
+ "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24281.1",
+ "Microsoft.DotNet.SharedFramework.Sdk": "9.0.0-beta.24281.1",
"Microsoft.Build.NoTargets": "3.7.0",
"Microsoft.Build.Traversal": "3.4.0",
"Microsoft.NET.Sdk.IL": "9.0.0-preview.5.24272.3"
diff --git a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj
index a37abf7a0c116..1586ba4132120 100644
--- a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj
+++ b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj
@@ -237,7 +237,9 @@
Common\System\Collections\Generic\ArrayBuilder.cs
-
+
+
+
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs
index 7c3cad7d86637..b84c9aec7d68f 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs
@@ -816,11 +816,7 @@ public unsafe void Initialize()
RuntimeType arrayType = (RuntimeType)GetType();
- if (arrayType.GenericCache is not ArrayInitializeCache cache)
- {
- cache = new ArrayInitializeCache(arrayType);
- arrayType.GenericCache = cache;
- }
+ ArrayInitializeCache cache = arrayType.GetOrCreateCacheEntry();
delegate*[ constructorFtn = cache.ConstructorEntrypoint;
ref byte arrayRef = ref MemoryMarshal.GetArrayDataReference(this);
@@ -833,17 +829,21 @@ public unsafe void Initialize()
}
}
- private sealed unsafe partial class ArrayInitializeCache
+ internal sealed unsafe partial class ArrayInitializeCache : RuntimeType.IGenericCacheEntry]
{
internal readonly delegate*[ ConstructorEntrypoint;
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Array_GetElementConstructorEntrypoint")]
private static partial delegate*][ GetElementConstructorEntrypoint(QCallTypeHandle arrayType);
- public ArrayInitializeCache(RuntimeType arrayType)
+ private ArrayInitializeCache(delegate*][ constructorEntrypoint)
{
- ConstructorEntrypoint = GetElementConstructorEntrypoint(new QCallTypeHandle(ref arrayType));
+ ConstructorEntrypoint = constructorEntrypoint;
}
+
+ public static ArrayInitializeCache Create(RuntimeType arrayType) => new(GetElementConstructorEntrypoint(new QCallTypeHandle(ref arrayType)));
+ public void InitializeCompositeCache(RuntimeType.CompositeCacheEntry compositeEntry) => compositeEntry._arrayInitializeCache = this;
+ public static ref ArrayInitializeCache? GetStorageRef(RuntimeType.CompositeCacheEntry compositeEntry) => ref compositeEntry._arrayInitializeCache;
}
}
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs
index cc46e2a75d8b2..9c92874f8ec27 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs
@@ -87,31 +87,49 @@ private static EnumInfo] GetEnumInfo(RuntimeType enumType, bo
typeof(TStorage) == typeof(nuint) || typeof(TStorage) == typeof(float) || typeof(TStorage) == typeof(double) || typeof(TStorage) == typeof(char),
$"Unexpected {nameof(TStorage)} == {typeof(TStorage)}");
- return enumType.GenericCache is EnumInfo info && (!getNames || info.Names is not null) ?
+ return enumType.FindCacheEntry>() is {} info && (!getNames || info.Names is not null) ?
info :
InitializeEnumInfo(enumType, getNames);
[MethodImpl(MethodImplOptions.NoInlining)]
static EnumInfo InitializeEnumInfo(RuntimeType enumType, bool getNames)
+ {
+ // If we're asked to get the cache with names,
+ // force that copy into the cache even if we already have a cache entry without names
+ // so we don't have to recompute the names if asked again.
+ return getNames
+ ? enumType.ReplaceCacheEntry(EnumInfo.Create(enumType, getNames: true))
+ : enumType.GetOrCreateCacheEntry>();
+ }
+ }
+
+ internal sealed partial class EnumInfo : RuntimeType.IGenericCacheEntry>
+ {
+ public static EnumInfo Create(RuntimeType type, bool getNames)
{
TStorage[]? values = null;
string[]? names = null;
GetEnumValuesAndNames(
- new QCallTypeHandle(ref enumType),
+ new QCallTypeHandle(ref type),
ObjectHandleOnStack.Create(ref values),
ObjectHandleOnStack.Create(ref names),
getNames ? Interop.BOOL.TRUE : Interop.BOOL.FALSE);
Debug.Assert(values!.GetType() == typeof(TStorage[]));
- Debug.Assert(!getNames || names!.GetType() == typeof(string[]));
- bool hasFlagsAttribute = enumType.IsDefined(typeof(FlagsAttribute), inherit: false);
+ bool hasFlagsAttribute = type.IsDefined(typeof(FlagsAttribute), inherit: false);
- var entry = new EnumInfo(hasFlagsAttribute, values, names!);
- enumType.GenericCache = entry;
- return entry;
+ return new EnumInfo(hasFlagsAttribute, values, names!);
}
+
+ public static EnumInfo Create(RuntimeType type) => Create(type, getNames: false);
+
+ public void InitializeCompositeCache(RuntimeType.CompositeCacheEntry compositeEntry) => compositeEntry._enumInfo = this;
+
+ // This type is the only type that will be stored in the _enumInfo field, so we can use Unsafe.As here.
+ public static ref EnumInfo? GetStorageRef(RuntimeType.CompositeCacheEntry compositeEntry)
+ => ref Unsafe.As?>(ref compositeEntry._enumInfo);
}
}
}
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 51c60b74f4168..461922f7f017b 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
@@ -308,15 +308,6 @@ public static object GetUninitializedObject(
[LibraryImport(QCall, EntryPoint = "ObjectNative_AllocateUninitializedClone")]
internal static partial void AllocateUninitializedClone(ObjectHandleOnStack objHandle);
- /// true if given type is reference type or value type that contains references
- [Intrinsic]
- public static bool IsReferenceOrContainsReferences()
- {
- // The body of this function will be replaced by the EE with unsafe code!!!
- // See getILIntrinsicImplementationForRuntimeHelpers for how this happens.
- throw new InvalidOperationException();
- }
-
/// true if given type is bitwise equatable (memcmp can be used for equality checking)
///
/// Only use the result of this for Equals() comparison, not for CompareTo() comparison.
@@ -518,32 +509,7 @@ private static unsafe void DispatchTailCalls(
if (type.IsNullHandle())
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.type);
- TypeHandle handle = type.GetNativeTypeHandle();
-
- if (handle.IsTypeDesc)
- throw new ArgumentException(SR.Arg_TypeNotSupported);
-
- MethodTable* pMT = handle.AsMethodTable();
-
- if (pMT->ContainsGenericVariables)
- throw new ArgumentException(SR.Arg_TypeNotSupported);
-
- if (pMT->IsValueType)
- {
- if (pMT->IsByRefLike)
- throw new NotSupportedException(SR.NotSupported_ByRefLike);
-
- if (MethodTable.AreSameType(pMT, (MethodTable*)RuntimeTypeHandle.ToIntPtr(typeof(void).TypeHandle)))
- throw new ArgumentException(SR.Arg_TypeNotSupported);
-
- object? result = Box(pMT, ref target);
- GC.KeepAlive(type);
- return result;
- }
- else
- {
- return Unsafe.As(ref target);
- }
+ return type.GetRuntimeType().Box(ref target);
}
[LibraryImport(QCall, EntryPoint = "ReflectionInvocation_SizeOf")]
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/ComEventsHelper.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/ComEventsHelper.cs
index ef0e80bde52a7..dbeb35b013fad 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/ComEventsHelper.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/ComEventsHelper.cs
@@ -16,7 +16,7 @@
// event sinks are COM objects implementing source interfaces. Once an event sink is passed to the COM
// server (through a mechanism known as 'binding/advising to connection point'), COM server will be
// calling source interface methods to "fire events".
-// See https://docs.microsoft.com/cpp/mfc/connection-points
+// See https://learn.microsoft.com/cpp/mfc/connection-points
//
// There are few interesting obervations about source interfaces. Usually source interfaces are defined
// as 'dispinterface' - meaning that only late-bound invocations on this interface are allowed. Even
diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
index 472f4f6318a3d..7eddc635ef76b 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
@@ -270,24 +270,27 @@ internal static void GetActivationInfo(
RuntimeType rt,
out delegate* pfnAllocator,
out void* vAllocatorFirstArg,
- out delegate* pfnCtor,
+ out delegate* pfnRefCtor,
+ out delegate*[ pfnValueCtor,
out bool ctorIsPublic)
{
Debug.Assert(rt != null);
delegate*] pfnAllocatorTemp = default;
void* vAllocatorFirstArgTemp = default;
- delegate* pfnCtorTemp = default;
+ delegate* pfnRefCtorTemp = default;
+ delegate*[ pfnValueCtorTemp = default;
Interop.BOOL fCtorIsPublicTemp = default;
GetActivationInfo(
ObjectHandleOnStack.Create(ref rt),
&pfnAllocatorTemp, &vAllocatorFirstArgTemp,
- &pfnCtorTemp, &fCtorIsPublicTemp);
+ &pfnRefCtorTemp, &pfnValueCtorTemp, &fCtorIsPublicTemp);
pfnAllocator = pfnAllocatorTemp;
vAllocatorFirstArg = vAllocatorFirstArgTemp;
- pfnCtor = pfnCtorTemp;
+ pfnRefCtor = pfnRefCtorTemp;
+ pfnValueCtor = pfnValueCtorTemp;
ctorIsPublic = fCtorIsPublicTemp != Interop.BOOL.FALSE;
}
@@ -296,7 +299,8 @@ private static partial void GetActivationInfo(
ObjectHandleOnStack pRuntimeType,
delegate*]* ppfnAllocator,
void** pvAllocatorFirstArg,
- delegate** ppfnCtor,
+ delegate** ppfnRefCtor,
+ delegate*[* ppfnValueCtor,
Interop.BOOL* pfCtorIsPublic);
#if FEATURE_COMINTEROP
diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.ActivatorCache.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.ActivatorCache.cs
index 4d73cfad39143..369d3bc5b8637 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.ActivatorCache.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.ActivatorCache.cs
@@ -13,7 +13,7 @@ internal sealed partial class RuntimeType
/// A cache which allows optimizing ] ,
/// , and related APIs.
///
- private sealed unsafe class ActivatorCache
+ internal sealed unsafe class ActivatorCache : IGenericCacheEntry
{
// The managed calli to the newobj allocator, plus its first argument (MethodTable*).
// In the case of the COM allocator, first arg is ComClassFactory*, not MethodTable*.
@@ -21,16 +21,19 @@ private sealed unsafe class ActivatorCache
private readonly void* _allocatorFirstArg;
// The managed calli to the parameterless ctor, taking "this" (as object) as its first argument.
- private readonly delegate* _pfnCtor;
+ private readonly delegate* _pfnRefCtor;
+ private readonly delegate*[ _pfnValueCtor;
private readonly bool _ctorIsPublic;
- private CreateUninitializedCache? _createUninitializedCache;
-
#if DEBUG
private readonly RuntimeType _originalRuntimeType;
#endif
- internal ActivatorCache(RuntimeType rt)
+ public static ActivatorCache Create(RuntimeType type) => new(type);
+ public void InitializeCompositeCache(RuntimeType.CompositeCacheEntry compositeEntry) => compositeEntry._activatorCache = this;
+ public static ref ActivatorCache? GetStorageRef(RuntimeType.CompositeCacheEntry compositeEntry) => ref compositeEntry._activatorCache;
+
+ private ActivatorCache(RuntimeType rt)
{
Debug.Assert(rt != null);
@@ -48,7 +51,7 @@ internal ActivatorCache(RuntimeType rt)
{
RuntimeTypeHandle.GetActivationInfo(rt,
out _pfnAllocator!, out _allocatorFirstArg,
- out _pfnCtor!, out _ctorIsPublic);
+ out _pfnRefCtor!, out _pfnValueCtor!, out _ctorIsPublic);
}
catch (Exception ex)
{
@@ -87,14 +90,29 @@ internal ActivatorCache(RuntimeType rt)
// would have thrown an exception if 'rt' were a normal reference type
// without a ctor.
- if (_pfnCtor == null)
+ if (_pfnRefCtor == null)
{
- static void CtorNoopStub(object? uninitializedObject) { }
- _pfnCtor = &CtorNoopStub; // we use null singleton pattern if no ctor call is necessary
+ static void RefCtorNoopStub(object? uninitializedObject) { }
+ _pfnRefCtor = &RefCtorNoopStub; // we use null singleton pattern if no ctor call is necessary
Debug.Assert(_ctorIsPublic); // implicit parameterless ctor is always considered public
}
+ if (rt.IsValueType)
+ {
+ if (_pfnValueCtor == null)
+ {
+ static void ValueRefCtorNoopStub(ref byte uninitializedObject) { }
+ _pfnValueCtor = &ValueRefCtorNoopStub; // we use null singleton pattern if no ctor call is necessary
+
+ Debug.Assert(_ctorIsPublic); // implicit parameterless ctor is always considered public
+ }
+ }
+ else
+ {
+ Debug.Assert(_pfnValueCtor == null); // Non-value types shouldn't have a value constructor.
+ }
+
// We don't need to worry about invoking cctors here. The runtime will figure it
// out for us when the instance ctor is called. For value types, because we're
// creating a boxed default(T), the static cctor is called when *any* instance
@@ -120,15 +138,15 @@ static void CtorNoopStub(object? uninitializedObject) { }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal void CallConstructor(object? uninitializedObject) => _pfnCtor(uninitializedObject);
+ internal void CallRefConstructor(object? uninitializedObject) => _pfnRefCtor(uninitializedObject);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal CreateUninitializedCache GetCreateUninitializedCache(RuntimeType rt)
+ internal void CallValueConstructor(ref byte uninitializedObject)
{
#if DEBUG
- CheckOriginalRuntimeType(rt);
+ Debug.Assert(_originalRuntimeType.IsValueType);
#endif
- return _createUninitializedCache ??= new CreateUninitializedCache(rt);
+ _pfnValueCtor(ref uninitializedObject);
}
#if DEBUG
diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.BoxCache.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.BoxCache.cs
new file mode 100644
index 0000000000000..b687947f4dde8
--- /dev/null
+++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.BoxCache.cs
@@ -0,0 +1,146 @@
+// 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;
+
+namespace System
+{
+ internal sealed partial class RuntimeType
+ {
+ /// ]
+ /// A cache which allows optimizing .
+ ///
+ internal sealed unsafe partial class BoxCache : IGenericCacheEntry
+ {
+ public static BoxCache Create(RuntimeType type) => new(type);
+ public void InitializeCompositeCache(CompositeCacheEntry compositeEntry) => compositeEntry._boxCache = this;
+ public static ref BoxCache? GetStorageRef(CompositeCacheEntry compositeEntry) => ref compositeEntry._boxCache;
+
+ // The managed calli to the newobj allocator, plus its first argument
+ private readonly delegate* _pfnAllocator;
+ private readonly void* _allocatorFirstArg;
+ private readonly int _nullableValueOffset;
+ private readonly uint _valueTypeSize;
+ private readonly MethodTable* _pMT;
+
+#if DEBUG
+ private readonly RuntimeType _originalRuntimeType;
+#endif
+
+ private BoxCache(RuntimeType rt)
+ {
+ Debug.Assert(rt != null);
+
+#if DEBUG
+ _originalRuntimeType = rt;
+#endif
+
+ TypeHandle handle = rt.TypeHandle.GetNativeTypeHandle();
+
+ if (handle.IsTypeDesc)
+ throw new ArgumentException(SR.Arg_TypeNotSupported);
+
+ _pMT = handle.AsMethodTable();
+
+ // For value types, this is checked in GetBoxInfo,
+ // but for non-value types, we still need to check this case for consistent behavior.
+ if (_pMT->ContainsGenericVariables)
+ throw new ArgumentException(SR.Arg_TypeNotSupported);
+
+ if (_pMT->IsValueType)
+ {
+ GetBoxInfo(rt, out _pfnAllocator, out _allocatorFirstArg, out _nullableValueOffset, out _valueTypeSize);
+ }
+ }
+
+ internal object? Box(RuntimeType rt, ref byte data)
+ {
+#if DEBUG
+ if (_originalRuntimeType != rt)
+ {
+ Debug.Fail("Caller passed the wrong RuntimeType to this routine."
+ + Environment.NewLineConst + "Expected: " + (_originalRuntimeType ?? (object)"")
+ + Environment.NewLineConst + "Actual: " + (rt ?? (object)""));
+ }
+#endif
+ if (_pfnAllocator == null)
+ {
+ // If the allocator is null, then we shouldn't allocate and make a copy,
+ // we should return the data as the object it currently is.
+ return Unsafe.As(ref data);
+ }
+
+ ref byte source = ref data;
+
+ byte maybeNullableHasValue = Unsafe.ReadUnaligned(ref source);
+
+ if (_nullableValueOffset != 0)
+ {
+ if (maybeNullableHasValue == 0)
+ {
+ return null;
+ }
+ source = ref Unsafe.Add(ref source, _nullableValueOffset);
+ }
+
+ object result = _pfnAllocator(_allocatorFirstArg);
+ GC.KeepAlive(rt);
+
+ if (_pMT->ContainsGCPointers)
+ {
+ Buffer.BulkMoveWithWriteBarrier(ref result.GetRawData(), ref source, _valueTypeSize);
+ }
+ else
+ {
+ SpanHelpers.Memmove(ref result.GetRawData(), ref source, _valueTypeSize);
+ }
+
+ return result;
+ }
+
+ ///
+ /// Given a RuntimeType, returns information about how to box instances
+ /// of it via calli semantics.
+ ///
+ private static void GetBoxInfo(
+ RuntimeType rt,
+ out delegate* pfnAllocator,
+ out void* vAllocatorFirstArg,
+ out int nullableValueOffset,
+ out uint valueTypeSize)
+ {
+ Debug.Assert(rt != null);
+
+ delegate* pfnAllocatorTemp = default;
+ void* vAllocatorFirstArgTemp = default;
+ int nullableValueOffsetTemp = default;
+ uint valueTypeSizeTemp = default;
+
+ GetBoxInfo(
+ new QCallTypeHandle(ref rt),
+ &pfnAllocatorTemp, &vAllocatorFirstArgTemp,
+ &nullableValueOffsetTemp, &valueTypeSizeTemp);
+
+ pfnAllocator = pfnAllocatorTemp;
+ vAllocatorFirstArg = vAllocatorFirstArgTemp;
+ nullableValueOffset = nullableValueOffsetTemp;
+ valueTypeSize = valueTypeSizeTemp;
+ }
+
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ReflectionInvocation_GetBoxInfo")]
+ private static partial void GetBoxInfo(
+ QCallTypeHandle type,
+ delegate** ppfnAllocator,
+ void** pvAllocatorFirstArg,
+ int* pNullableValueOffset,
+ uint* pValueTypeSize);
+ }
+
+ internal object? Box(ref byte data)
+ {
+ return GetOrCreateCacheEntry().Box(this, ref data);
+ }
+ }
+}
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 c6ea76fde9b85..28c03245f6dde 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
@@ -1454,11 +1454,8 @@ internal T[] GetMemberList(MemberListType listType, string? name, CacheType cach
private static CerHashtable s_methodInstantiations;
private static object? s_methodInstantiationsLock;
private string? m_defaultMemberName;
- // Generic cache for rare scenario specific data. Used for:
- // - Enum names and values (EnumInfo)
- // - Activator.CreateInstance (ActivatorCache)
- // - Array.Initialize (ArrayInitializeCache)
- private object? m_genericCache;
+ // Generic cache for rare scenario specific data.
+ private IGenericCacheEntry? m_genericCache;
private object[]? _emptyArray; // Object array cache for Attribute.GetCustomAttributes() pathological no-result case.
private RuntimeType? _genericTypeDefinition;
#endregion
@@ -1501,30 +1498,31 @@ private MemberInfoCache GetMemberCache(ref MemberInfoCache? m_cache)
#region Internal Members
+ internal ref IGenericCacheEntry? GenericCache => ref m_genericCache;
- ///
- /// Generic cache for rare scenario specific data. It is used to cache either Enum names, Enum values,
- /// the Activator cache or function pointer parameters.
- ///
- internal object? GenericCache
+ internal sealed class FunctionPointerCache : IGenericCacheEntry
{
- get => m_genericCache;
- set => m_genericCache = value;
+ public Type[] FunctionPointerReturnAndParameterTypes { get; }
+
+ private FunctionPointerCache(Type[] functionPointerReturnAndParameterTypes)
+ {
+ FunctionPointerReturnAndParameterTypes = functionPointerReturnAndParameterTypes;
+ }
+
+ public static FunctionPointerCache Create(RuntimeType type)
+ {
+ Debug.Assert(type.IsFunctionPointer);
+ return new(RuntimeTypeHandle.GetArgumentTypesFromFunctionPointer(type));
+ }
+ public void InitializeCompositeCache(RuntimeType.CompositeCacheEntry compositeEntry) => compositeEntry._functionPointerCache = this;
+ public static ref FunctionPointerCache? GetStorageRef(RuntimeType.CompositeCacheEntry compositeEntry) => ref compositeEntry._functionPointerCache;
}
internal Type[] FunctionPointerReturnAndParameterTypes
{
get
{
- Debug.Assert(m_runtimeType.IsFunctionPointer);
- Type[]? value = (Type[]?)GenericCache;
- if (value == null)
- {
- GenericCache = value = RuntimeTypeHandle.GetArgumentTypesFromFunctionPointer(m_runtimeType);
- Debug.Assert(value.Length > 0);
- }
-
- return value;
+ return m_runtimeType.GetOrCreateCacheEntry().FunctionPointerReturnAndParameterTypes;
}
}
@@ -1930,10 +1928,23 @@ internal FieldInfo GetField(RuntimeFieldHandleInternal field)
return retval;
}
- internal object? GenericCache
+ internal T GetOrCreateCacheEntry()
+ where T : class, IGenericCacheEntry
+ {
+ return IGenericCacheEntry.GetOrCreate(this);
+ }
+
+ internal T? FindCacheEntry()
+ where T : class, IGenericCacheEntry
{
- get => CacheIfExists?.GenericCache;
- set => Cache.GenericCache = value;
+ return IGenericCacheEntry.Find(this);
+ }
+
+ internal T ReplaceCacheEntry(T entry)
+ where T : class, IGenericCacheEntry
+ {
+ IGenericCacheEntry.Replace(this, entry);
+ return entry;
}
internal static FieldInfo GetFieldInfo(IRuntimeFieldInfo fieldHandle)
@@ -2376,7 +2387,7 @@ private static bool FilterApplyMethodBase(
#endregion
- #endregion
+#endregion
#region Private Data Members
@@ -3886,22 +3897,7 @@ private void CreateInstanceCheckThis()
[DebuggerHidden]
internal object GetUninitializedObject()
{
- object? genericCache = GenericCache;
-
- if (genericCache is not CreateUninitializedCache cache)
- {
- if (genericCache is ActivatorCache activatorCache)
- {
- cache = activatorCache.GetCreateUninitializedCache(this);
- }
- else
- {
- cache = new CreateUninitializedCache(this);
- GenericCache = cache;
- }
- }
-
- return cache.CreateUninitializedObject(this);
+ return GetOrCreateCacheEntry().CreateUninitializedObject(this);
}
///
@@ -3914,11 +3910,7 @@ internal object GetUninitializedObject()
// Get or create the cached factory. Creating the cache will fail if one
// of our invariant checks fails; e.g., no appropriate ctor found.
- if (GenericCache is not ActivatorCache cache)
- {
- cache = new ActivatorCache(this);
- GenericCache = cache;
- }
+ ActivatorCache cache = GetOrCreateCacheEntry();
if (!cache.CtorIsPublic && publicOnly)
{
@@ -3932,7 +3924,7 @@ internal object GetUninitializedObject()
object? obj = cache.CreateUninitializedObject(this);
try
{
- cache.CallConstructor(obj);
+ cache.CallRefConstructor(obj);
}
catch (Exception e) when (wrapExceptions)
{
@@ -3942,26 +3934,23 @@ internal object GetUninitializedObject()
return obj;
}
- // Specialized version of the above for Activator.CreateInstance()
+ // Specialized version of CreateInstanceDefaultCtor() for Activator.CreateInstance()
[DebuggerStepThrough]
[DebuggerHidden]
internal object? CreateInstanceOfT()
{
- if (GenericCache is not ActivatorCache cache)
- {
- cache = new ActivatorCache(this);
- GenericCache = cache;
- }
+ ActivatorCache cache = GetOrCreateCacheEntry();
if (!cache.CtorIsPublic)
{
throw new MissingMethodException(SR.Format(SR.Arg_NoDefCTor, this));
}
+ // We reuse ActivatorCache here to ensure that we aren't always creating two entries in the cache.
object? obj = cache.CreateUninitializedObject(this);
try
{
- cache.CallConstructor(obj);
+ cache.CallRefConstructor(obj);
}
catch (Exception e)
{
@@ -3971,6 +3960,30 @@ internal object GetUninitializedObject()
return obj;
}
+ // Specialized version of CreateInstanceDefaultCtor() for Activator.CreateInstance()
+ [DebuggerStepThrough]
+ [DebuggerHidden]
+ internal void CallDefaultStructConstructor(ref byte data)
+ {
+ Debug.Assert(IsValueType);
+
+ ActivatorCache cache = GetOrCreateCacheEntry();
+
+ if (!cache.CtorIsPublic)
+ {
+ throw new MissingMethodException(SR.Format(SR.Arg_NoDefCTor, this));
+ }
+
+ try
+ {
+ cache.CallValueConstructor(ref data);
+ }
+ catch (Exception e)
+ {
+ throw new TargetInvocationException(e);
+ }
+ }
+
internal void InvalidateCachedNestedType() => Cache.InvalidateCachedNestedType();
internal bool IsGenericCOMObjectImpl() => RuntimeTypeHandle.IsComObject(this, true);
diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CreateUninitializedCache.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CreateUninitializedCache.CoreCLR.cs
index 710b1b507e4ef..e70078403f89c 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CreateUninitializedCache.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CreateUninitializedCache.CoreCLR.cs
@@ -12,8 +12,12 @@ internal sealed partial class RuntimeType
///
/// A cache which allows optimizing .
///
- private sealed unsafe partial class CreateUninitializedCache
+ internal sealed unsafe partial class CreateUninitializedCache : IGenericCacheEntry
{
+ public static CreateUninitializedCache Create(RuntimeType type) => new(type);
+ public void InitializeCompositeCache(RuntimeType.CompositeCacheEntry compositeEntry) => compositeEntry._createUninitializedCache = this;
+ public static ref CreateUninitializedCache? GetStorageRef(RuntimeType.CompositeCacheEntry compositeEntry) => ref compositeEntry._createUninitializedCache;
+
// The managed calli to the newobj allocator, plus its first argument (MethodTable*).
private readonly delegate* _pfnAllocator;
private readonly void* _allocatorFirstArg;
@@ -22,7 +26,7 @@ private sealed unsafe partial class CreateUninitializedCache
private readonly RuntimeType _originalRuntimeType;
#endif
- internal CreateUninitializedCache(RuntimeType rt)
+ private CreateUninitializedCache(RuntimeType rt)
{
Debug.Assert(rt != null);
diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.GenericCache.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.GenericCache.cs
new file mode 100644
index 0000000000000..d59e096828c75
--- /dev/null
+++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.GenericCache.cs
@@ -0,0 +1,168 @@
+// 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;
+using System.Runtime.InteropServices;
+using System.Threading;
+using static System.RuntimeType;
+
+namespace System
+{
+ internal sealed partial class RuntimeType
+ {
+ ///
+ /// A composite cache entry that can store multiple cache entries of different kinds.
+ ///
+ internal sealed class CompositeCacheEntry : IGenericCacheEntry
+ {
+ internal ActivatorCache? _activatorCache;
+ internal CreateUninitializedCache? _createUninitializedCache;
+ internal RuntimeTypeCache.FunctionPointerCache? _functionPointerCache;
+ internal Array.ArrayInitializeCache? _arrayInitializeCache;
+ internal IGenericCacheEntry? _enumInfo;
+ internal BoxCache? _boxCache;
+
+ void IGenericCacheEntry.InitializeCompositeCache(CompositeCacheEntry compositeEntry) => throw new UnreachableException();
+ }
+
+ ///
+ /// A base interface for all cache entries that can be stored in .
+ ///
+ internal interface IGenericCacheEntry
+ {
+ public void InitializeCompositeCache(CompositeCacheEntry compositeEntry);
+ }
+
+ ///
+ /// A typed cache entry. This type provides a base type that handles contruction of entries and maintenance of
+ /// the in a .
+ ///
+ /// The cache entry type.
+ internal interface IGenericCacheEntry : IGenericCacheEntry
+ where TCache : class, IGenericCacheEntry
+ {
+ public static abstract TCache Create(RuntimeType type);
+
+ public static abstract ref TCache? GetStorageRef(CompositeCacheEntry compositeEntry);
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static TCache GetOrCreate(RuntimeType type)
+ {
+ ref IGenericCacheEntry? genericCache = ref type.Cache.GenericCache;
+ // Read the GenericCache once to avoid multiple reads of the same field.
+ IGenericCacheEntry? currentCache = genericCache;
+ if (currentCache is not null)
+ {
+ if (currentCache is TCache existing)
+ {
+ return existing;
+ }
+ if (currentCache is CompositeCacheEntry composite)
+ {
+ TCache? existingComposite = TCache.GetStorageRef(composite);
+ if (existingComposite != null)
+ return existingComposite;
+ }
+ }
+
+ return CreateAndCache(type);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static TCache? Find(RuntimeType type)
+ {
+ ref IGenericCacheEntry? genericCache = ref type.Cache.GenericCache;
+ // Read the GenericCache once to avoid multiple reads of the same field.
+ IGenericCacheEntry? currentCache = genericCache;
+ if (currentCache is not null)
+ {
+ if (currentCache is TCache existing)
+ {
+ return existing;
+ }
+ if (currentCache is CompositeCacheEntry composite)
+ {
+ return TCache.GetStorageRef(composite);
+ }
+ }
+
+ return null;
+ }
+
+ public static TCache Replace(RuntimeType type, TCache newEntry)
+ {
+ ref IGenericCacheEntry? genericCache = ref type.Cache.GenericCache;
+
+ // If the existing cache is of the same type, we can replace it directly,
+ // as long as it is not upgraded to a composite cache simultaneously.
+ while (true)
+ {
+ IGenericCacheEntry? existing = genericCache;
+ if (existing is not (null or TCache))
+ break; // We lost the race and we can no longer replace the cache directly.
+
+ if (Interlocked.CompareExchange(ref genericCache, newEntry, existing) == existing)
+ return newEntry;
+ // We lost the race, try again.
+ }
+
+ // If we get here, either we have a composite cache or we need to upgrade to a composite cache.
+ while (true)
+ {
+ IGenericCacheEntry existing = genericCache!;
+ if (existing is not CompositeCacheEntry compositeCache)
+ {
+ compositeCache = new CompositeCacheEntry();
+ existing.InitializeCompositeCache(compositeCache);
+ if (Interlocked.CompareExchange(ref genericCache, compositeCache, existing) != existing)
+ continue; // We lost the race, try again.
+ }
+
+ TCache? existingEntry = TCache.GetStorageRef(compositeCache);
+ if (Interlocked.CompareExchange(ref TCache.GetStorageRef(compositeCache), newEntry, existingEntry) == existingEntry)
+ return newEntry;
+ // We lost the race, try again.
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static TCache CreateAndCache(RuntimeType type)
+ {
+ while (true)
+ {
+ ref IGenericCacheEntry? genericCache = ref type.Cache.GenericCache;
+
+ // Update to CompositeCacheEntry if necessary
+ IGenericCacheEntry? existing = genericCache;
+ if (existing is null)
+ {
+ TCache newEntry = TCache.Create(type);
+ if (Interlocked.CompareExchange(ref genericCache, newEntry, null) == null)
+ return newEntry;
+ // We lost the race, try again.
+ }
+ else
+ {
+ if (existing is TCache existingTyped)
+ return existingTyped;
+
+ if (existing is not CompositeCacheEntry compositeCache)
+ {
+ compositeCache = new CompositeCacheEntry();
+ existing.InitializeCompositeCache(compositeCache);
+ if (Interlocked.CompareExchange(ref genericCache, compositeCache, existing) != existing)
+ continue; // We lost the race, try again.
+ }
+
+ TCache newEntry = TCache.Create(type);
+ if (Interlocked.CompareExchange(ref TCache.GetStorageRef(compositeCache), newEntry, null) == null)
+ return newEntry;
+ // We lost the race, try again.
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/coreclr/binder/assemblyname.cpp b/src/coreclr/binder/assemblyname.cpp
index 0c96f6be47ec2..245c72c8d6a1f 100644
--- a/src/coreclr/binder/assemblyname.cpp
+++ b/src/coreclr/binder/assemblyname.cpp
@@ -25,7 +25,7 @@
namespace
{
- // See https://docs.microsoft.com/dotnet/framework/reflection-and-codedom/specifying-fully-qualified-type-names#specifying-assembly-names
+ // See https://learn.microsoft.com/dotnet/framework/reflection-and-codedom/specifying-fully-qualified-type-names#specifying-assembly-names
const WCHAR* s_neutralCulture = W("neutral");
}
diff --git a/src/coreclr/debug/createdump/crashinfo.cpp b/src/coreclr/debug/createdump/crashinfo.cpp
index 72c27bd38ee42..32a372d373862 100644
--- a/src/coreclr/debug/createdump/crashinfo.cpp
+++ b/src/coreclr/debug/createdump/crashinfo.cpp
@@ -319,7 +319,14 @@ CrashInfo::InitializeDAC(DumpType dumpType)
m_dacModule = dlopen(dacPath.c_str(), RTLD_LAZY);
if (m_dacModule == nullptr)
{
- printf_error("InitializeDAC: dlopen(%s) FAILED %s\n", dacPath.c_str(), dlerror());
+ if (m_appModel == AppModelType::SingleFile)
+ {
+ printf_error("Only full dumps are supported by single file apps. Change the dump type to full (DOTNET_DbgMiniDumpType=4)\n");
+ }
+ else
+ {
+ printf_error("InitializeDAC: dlopen(%s) FAILED %s\n", dacPath.c_str(), dlerror());
+ }
goto exit;
}
pfnDllMain = (PFN_DLLMAIN)dlsym(m_dacModule, "DllMain");
diff --git a/src/coreclr/debug/createdump/createdumpmain.cpp b/src/coreclr/debug/createdump/createdumpmain.cpp
index e39538c4cb1c3..0d9dc69686538 100644
--- a/src/coreclr/debug/createdump/createdumpmain.cpp
+++ b/src/coreclr/debug/createdump/createdumpmain.cpp
@@ -229,6 +229,7 @@ int createdump_main(const int argc, const char* argv[])
exitCode = -1;
}
+ fflush(stderr);
fflush(g_stdout);
if (g_logfile != nullptr)
@@ -352,7 +353,7 @@ GetTimeStamp()
#ifdef HOST_UNIX
static void
-trace_prefix()
+trace_prefix(const char* format, va_list args)
{
// Only add this prefix if logging to the console
if (g_logfile == nullptr)
@@ -360,6 +361,8 @@ trace_prefix()
fprintf(g_stdout, "[createdump] ");
}
fprintf(g_stdout, "%08" PRIx64 " ", GetTimeStamp());
+ vfprintf(g_stdout, format, args);
+ fflush(g_stdout);
}
void
@@ -369,9 +372,7 @@ trace_printf(const char* format, ...)
{
va_list args;
va_start(args, format);
- trace_prefix();
- vfprintf(g_stdout, format, args);
- fflush(g_stdout);
+ trace_prefix(format, args);
va_end(args);
}
}
@@ -383,9 +384,7 @@ trace_verbose_printf(const char* format, ...)
{
va_list args;
va_start(args, format);
- trace_prefix();
- vfprintf(g_stdout, format, args);
- fflush(g_stdout);
+ trace_prefix(format, args);
va_end(args);
}
}
@@ -397,9 +396,7 @@ CrashInfo::Trace(const char* format, ...)
{
va_list args;
va_start(args, format);
- trace_prefix();
- vfprintf(g_stdout, format, args);
- fflush(g_stdout);
+ trace_prefix(format, args);
va_end(args);
}
}
@@ -411,9 +408,7 @@ CrashInfo::TraceVerbose(const char* format, ...)
{
va_list args;
va_start(args, format);
- trace_prefix();
- vfprintf(g_stdout, format, args);
- fflush(g_stdout);
+ trace_prefix(format, args);
va_end(args);
}
}
diff --git a/src/coreclr/debug/daccess/dacimpl.h b/src/coreclr/debug/daccess/dacimpl.h
index 8b1771d7132e3..4b05e401a06b1 100644
--- a/src/coreclr/debug/daccess/dacimpl.h
+++ b/src/coreclr/debug/daccess/dacimpl.h
@@ -1229,6 +1229,7 @@ class ClrDataAccess
HRESULT Initialize(void);
+ HRESULT GetThreadDataImpl(CLRDATA_ADDRESS threadAddr, struct DacpThreadData *threadData);
HRESULT GetThreadStoreDataImpl(struct DacpThreadStoreData *data);
BOOL IsExceptionFromManagedCode(EXCEPTION_RECORD * pExceptionRecord);
diff --git a/src/coreclr/debug/daccess/request.cpp b/src/coreclr/debug/daccess/request.cpp
index 4657aadf22965..5353c93a89228 100644
--- a/src/coreclr/debug/daccess/request.cpp
+++ b/src/coreclr/debug/daccess/request.cpp
@@ -761,11 +761,52 @@ ClrDataAccess::GetHeapAllocData(unsigned int count, struct DacpGenerationAllocDa
return hr;
}
-HRESULT
-ClrDataAccess::GetThreadData(CLRDATA_ADDRESS threadAddr, struct DacpThreadData *threadData)
+HRESULT ClrDataAccess::GetThreadData(CLRDATA_ADDRESS threadAddr, struct DacpThreadData* threadData)
{
SOSDacEnter();
+ if (m_cdacSos != NULL)
+ {
+ hr = m_cdacSos->GetThreadData(threadAddr, threadData);
+ if (FAILED(hr))
+ {
+ hr = GetThreadDataImpl(threadAddr, threadData);
+ }
+#ifdef _DEBUG
+ else
+ {
+ DacpThreadData threadDataLocal;
+ HRESULT hrLocal = GetThreadDataImpl(threadAddr, &threadDataLocal);
+ _ASSERTE(hr == hrLocal);
+ _ASSERTE(threadData->corThreadId == threadDataLocal.corThreadId);
+ _ASSERTE(threadData->osThreadId == threadDataLocal.osThreadId);
+ _ASSERTE(threadData->state == threadDataLocal.state);
+ _ASSERTE(threadData->preemptiveGCDisabled == threadDataLocal.preemptiveGCDisabled);
+ _ASSERTE(threadData->allocContextPtr == threadDataLocal.allocContextPtr);
+ _ASSERTE(threadData->allocContextLimit == threadDataLocal.allocContextLimit);
+ _ASSERTE(threadData->context == threadDataLocal.context);
+ _ASSERTE(threadData->domain == threadDataLocal.domain);
+ _ASSERTE(threadData->pFrame == threadDataLocal.pFrame);
+ _ASSERTE(threadData->lockCount == threadDataLocal.lockCount);
+ _ASSERTE(threadData->firstNestedException == threadDataLocal.firstNestedException);
+ _ASSERTE(threadData->teb == threadDataLocal.teb);
+ _ASSERTE(threadData->fiberData == threadDataLocal.fiberData);
+ _ASSERTE(threadData->lastThrownObjectHandle == threadDataLocal.lastThrownObjectHandle);
+ _ASSERTE(threadData->nextThread == threadDataLocal.nextThread);;
+ }
+#endif
+ }
+ else
+ {
+ hr = GetThreadDataImpl(threadAddr, threadData);
+ }
+
+ SOSDacLeave();
+ return hr;
+}
+
+HRESULT ClrDataAccess::GetThreadDataImpl(CLRDATA_ADDRESS threadAddr, struct DacpThreadData *threadData)
+{
// marshal the Thread object from the target
Thread* thread = PTR_Thread(TO_TADDR(threadAddr));
@@ -804,8 +845,7 @@ ClrDataAccess::GetThreadData(CLRDATA_ADDRESS threadAddr, struct DacpThreadData *
thread->m_ExceptionState.m_currentExInfo.m_pPrevNestedInfo);
#endif // FEATURE_EH_FUNCLETS
- SOSDacLeave();
- return hr;
+ return S_OK;
}
#ifdef FEATURE_REJIT
diff --git a/src/coreclr/debug/di/shimstackwalk.cpp b/src/coreclr/debug/di/shimstackwalk.cpp
index 46213d4ca3649..a0d84f1a5ecb8 100644
--- a/src/coreclr/debug/di/shimstackwalk.cpp
+++ b/src/coreclr/debug/di/shimstackwalk.cpp
@@ -150,6 +150,14 @@ BOOL ShimStackWalk::ShouldTrackUMChain(StackWalkInfo * pswInfo)
if (m_pProcess->IsThreadSuspendedOrHijacked(m_pThread))
return FALSE;
+ // In the case the thread is throwing a managed exception,
+ // TS_SyncSuspended might not yet be set, resulting in IsThreadSuspendedOrHijacked
+ // returning false above. We need to check the exception state to make sure we don't
+ // track the chain in this case. Since we know the type of Frame we are dealing with,
+ // we can make a more accurate determination of whether we should track the chain.
+ if (GetInternalFrameType(pswInfo->GetCurrentInternalFrame()) == STUBFRAME_EXCEPTION)
+ return FALSE;
+
return TRUE;
}
diff --git a/src/coreclr/debug/runtimeinfo/datadescriptor.h b/src/coreclr/debug/runtimeinfo/datadescriptor.h
index 2687ceff55353..e14d29f38ad79 100644
--- a/src/coreclr/debug/runtimeinfo/datadescriptor.h
+++ b/src/coreclr/debug/runtimeinfo/datadescriptor.h
@@ -105,14 +105,21 @@ CDAC_TYPES_BEGIN()
CDAC_TYPE_BEGIN(Thread)
CDAC_TYPE_INDETERMINATE(Thread)
+CDAC_TYPE_FIELD(Thread, /*uint32*/, Id, cdac_offsets::Id)
+CDAC_TYPE_FIELD(Thread, /*nuint*/, OSId, cdac_offsets::OSId)
CDAC_TYPE_FIELD(Thread, GCHandle, GCHandle, cdac_offsets::ExposedObject)
+CDAC_TYPE_FIELD(Thread, GCHandle, LastThrownObject, cdac_offsets::LastThrownObject)
CDAC_TYPE_FIELD(Thread, pointer, LinkNext, cdac_offsets::Link)
CDAC_TYPE_END(Thread)
CDAC_TYPE_BEGIN(ThreadStore)
CDAC_TYPE_INDETERMINATE(ThreadStore)
-CDAC_TYPE_FIELD(ThreadStore, /*omit type*/, ThreadCount, cdac_offsets::ThreadCount)
-CDAC_TYPE_FIELD(ThreadStore, /*omit type*/, ThreadList, cdac_offsets::ThreadList)
+CDAC_TYPE_FIELD(ThreadStore, /*SLink*/, FirstThreadLink, cdac_offsets::FirstThreadLink)
+CDAC_TYPE_FIELD(ThreadStore, /*int32*/, ThreadCount, cdac_offsets::ThreadCount)
+CDAC_TYPE_FIELD(ThreadStore, /*int32*/, UnstartedCount, cdac_offsets::UnstartedCount)
+CDAC_TYPE_FIELD(ThreadStore, /*int32*/, BackgroundCount, cdac_offsets::BackgroundCount)
+CDAC_TYPE_FIELD(ThreadStore, /*int32*/, PendingCount, cdac_offsets::PendingCount)
+CDAC_TYPE_FIELD(ThreadStore, /*int32*/, DeadCount, cdac_offsets::DeadCount)
CDAC_TYPE_END(ThreadStore)
CDAC_TYPE_BEGIN(GCHandle)
@@ -123,6 +130,8 @@ CDAC_TYPES_END()
CDAC_GLOBALS_BEGIN()
CDAC_GLOBAL_POINTER(ThreadStore, &ThreadStore::s_pThreadStore)
+CDAC_GLOBAL_POINTER(FinalizerThread, &::g_pFinalizerThread)
+CDAC_GLOBAL_POINTER(GCThread, &::g_pSuspensionThread)
#if FEATURE_EH_FUNCLETS
CDAC_GLOBAL(FeatureEHFunclets, uint8, 1)
#else
diff --git a/src/coreclr/gc/env/gcenv.os.h b/src/coreclr/gc/env/gcenv.os.h
index 01ed27dac3e59..75015b77262dd 100644
--- a/src/coreclr/gc/env/gcenv.os.h
+++ b/src/coreclr/gc/env/gcenv.os.h
@@ -422,7 +422,7 @@ class GCToOSInterface
// Remarks:
// If a process runs with a restricted memory limit, it returns the limit. If there's no limit
// specified, it returns amount of actual physical memory.
- static uint64_t GetPhysicalMemoryLimit(bool* is_restricted=NULL);
+ static uint64_t GetPhysicalMemoryLimit(bool* is_restricted=NULL, bool refresh=false);
// Get memory status
// Parameters:
diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp
index ced393436f555..98e81eddd2c51 100644
--- a/src/coreclr/gc/gc.cpp
+++ b/src/coreclr/gc/gc.cpp
@@ -7318,10 +7318,14 @@ bool gc_heap::virtual_commit (void* address, size_t size, int bucket, int h_numb
#endif //USE_REGIONS
dprintf(3, ("commit-accounting: commit in %d [%p, %p) for heap %d", bucket, address, ((uint8_t*)address + size), h_number));
-
-#ifndef USE_REGIONS
- if (bucket != recorded_committed_ignored_bucket)
+ bool should_count =
+#ifdef USE_REGIONS
+ true;
+#else
+ (bucket != recorded_committed_ignored_bucket);
#endif //USE_REGIONS
+
+ if (should_count)
{
check_commit_cs.Enter();
bool exceeded_p = false;
@@ -7381,7 +7385,7 @@ bool gc_heap::virtual_commit (void* address, size_t size, int bucket, int h_numb
virtual_alloc_commit_for_heap (address, size, h_number)) :
GCToOSInterface::VirtualCommit(address, size));
- if (!commit_succeeded_p && heap_hard_limit)
+ if (!commit_succeeded_p && should_count)
{
check_commit_cs.Enter();
committed_by_oh[bucket] -= size;
@@ -18480,6 +18484,7 @@ bool gc_heap::should_retry_other_heap (int gen_number, size_t size)
}
}
+#ifdef BACKGROUND_GC
void gc_heap::bgc_record_uoh_allocation(int gen_number, size_t size)
{
assert((gen_number >= uoh_start_generation) && (gen_number < total_generation_count));
@@ -18502,6 +18507,7 @@ void gc_heap::bgc_record_uoh_allocation(int gen_number, size_t size)
uoh_a_no_bgc[gen_number - uoh_start_generation] += size;
}
}
+#endif //BACKGROUND_GC
allocation_state gc_heap::allocate_uoh (int gen_number,
size_t size,
@@ -50043,6 +50049,7 @@ void gc_heap::check_and_adjust_bgc_tuning (int gen_number, size_t physical_size,
}
#endif //BGC_SERVO_TUNING
+#ifdef BACKGROUND_GC
void gc_heap::get_and_reset_uoh_alloc_info()
{
total_uoh_a_last_bgc = 0;
@@ -50084,6 +50091,7 @@ void gc_heap::get_and_reset_uoh_alloc_info()
total_uoh_a_last_bgc = total_uoh_a_no_bgc + total_uoh_a_bgc_marking + total_uoh_a_bgc_planning;
}
+#endif //BACKGROUND_GC
bool gc_heap::is_pm_ratio_exceeded()
{
@@ -52832,7 +52840,7 @@ int gc_heap::refresh_memory_limit()
size_t old_heap_hard_limit_poh = heap_hard_limit_oh[poh];
bool old_hard_limit_config_p = hard_limit_config_p;
- total_physical_mem = GCToOSInterface::GetPhysicalMemoryLimit (&is_restricted_physical_mem);
+ total_physical_mem = GCToOSInterface::GetPhysicalMemoryLimit (&is_restricted_physical_mem, true);
bool succeed = true;
diff --git a/src/coreclr/gc/gcpriv.h b/src/coreclr/gc/gcpriv.h
index da6c2f17c0774..6738d33a3247f 100644
--- a/src/coreclr/gc/gcpriv.h
+++ b/src/coreclr/gc/gcpriv.h
@@ -1764,7 +1764,9 @@ class gc_heap
PER_HEAP_ISOLATED_METHOD void add_to_history();
+#ifdef BACKGROUND_GC
PER_HEAP_ISOLATED_METHOD void get_and_reset_uoh_alloc_info();
+#endif //BACKGROUND_GC
#ifdef BGC_SERVO_TUNING
// Currently BGC servo tuning is an experimental feature.
diff --git a/src/coreclr/gc/unix/gcenv.unix.cpp b/src/coreclr/gc/unix/gcenv.unix.cpp
index 686d67bfb509c..9219d8153a59d 100644
--- a/src/coreclr/gc/unix/gcenv.unix.cpp
+++ b/src/coreclr/gc/unix/gcenv.unix.cpp
@@ -1212,14 +1212,13 @@ size_t GCToOSInterface::GetVirtualMemoryMaxAddress()
// Remarks:
// If a process runs with a restricted memory limit, it returns the limit. If there's no limit
// specified, it returns amount of actual physical memory.
-uint64_t GCToOSInterface::GetPhysicalMemoryLimit(bool* is_restricted)
+uint64_t GCToOSInterface::GetPhysicalMemoryLimit(bool* is_restricted, bool refresh)
{
size_t restricted_limit;
if (is_restricted)
*is_restricted = false;
- // The limit was not cached
- if (g_RestrictedPhysicalMemoryLimit == 0)
+ if (g_RestrictedPhysicalMemoryLimit == 0 || refresh)
{
restricted_limit = GetRestrictedPhysicalMemoryLimit();
VolatileStore(&g_RestrictedPhysicalMemoryLimit, restricted_limit);
diff --git a/src/coreclr/gc/windows/gcenv.windows.cpp b/src/coreclr/gc/windows/gcenv.windows.cpp
index 608751dd169af..4d7cfd40381f9 100644
--- a/src/coreclr/gc/windows/gcenv.windows.cpp
+++ b/src/coreclr/gc/windows/gcenv.windows.cpp
@@ -969,7 +969,7 @@ size_t GCToOSInterface::GetVirtualMemoryLimit()
// Remarks:
// If a process runs with a restricted memory limit, it returns the limit. If there's no limit
// specified, it returns amount of actual physical memory.
-uint64_t GCToOSInterface::GetPhysicalMemoryLimit(bool* is_restricted)
+uint64_t GCToOSInterface::GetPhysicalMemoryLimit(bool* is_restricted, bool refresh)
{
if (is_restricted)
*is_restricted = false;
diff --git a/src/coreclr/gcinfo/gcinfodumper.cpp b/src/coreclr/gcinfo/gcinfodumper.cpp
index 8acb4ea2d6b4b..a71ebe0dffd23 100644
--- a/src/coreclr/gcinfo/gcinfodumper.cpp
+++ b/src/coreclr/gcinfo/gcinfodumper.cpp
@@ -226,26 +226,26 @@ BOOL GcInfoDumper::ReportPointerRecord (
#undef REG
#elif defined(TARGET_RISCV64)
#undef REG
-#define REG(reg, field) { offsetof(RiscV64VolatileContextPointer, field) }
- REG(zero, R0),
- REG(a0, A0),
- REG(a1, A1),
- REG(a2, A2),
- REG(a3, A3),
- REG(a4, A4),
- REG(a5, A5),
- REG(a6, A6),
- REG(a7, A7),
- REG(t0, T0),
- REG(t1, T1),
- REG(t2, T2),
- REG(t3, T3),
- REG(t4, T4),
- REG(t5, T5),
- REG(t6, T6),
-#undef REG
#define REG(reg, field) { offsetof(T_KNONVOLATILE_CONTEXT_POINTERS, field) }
+#define vREG(reg, field) { offsetof(RiscV64VolatileContextPointer, field) }
+ vREG(zero, R0),
+ REG(Ra, Ra),
+ { offsetof(T_CONTEXT, Sp) },
+ REG(Gp, Gp),
+ REG(Tp, Tp),
+ vREG(t0, T0),
+ vREG(t1, T1),
+ vREG(t2, T2),
+ REG(Fp, Fp),
REG(s1, S1),
+ vREG(a0, A0),
+ vREG(a1, A1),
+ vREG(a2, A2),
+ vREG(a3, A3),
+ vREG(a4, A4),
+ vREG(a5, A5),
+ vREG(a6, A6),
+ vREG(a7, A7),
REG(s2, S2),
REG(s3, S3),
REG(s4, S4),
@@ -256,13 +256,12 @@ BOOL GcInfoDumper::ReportPointerRecord (
REG(s9, S9),
REG(s10, S10),
REG(s11, S11),
- REG(ra, Ra),
- REG(gp, Gp),
- REG(tp, Tp),
- REG(fp, Fp),
- { offsetof(T_CONTEXT, Sp) },
+ vREG(t3, T3),
+ vREG(t4, T4),
+ vREG(t5, T5),
+ vREG(t6, T6),
+#undef vREG
#undef REG
-
#else
PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this platform.")
#endif
@@ -291,16 +290,11 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
iSPRegister = (offsetof(T_CONTEXT, Sp) - offsetof(T_CONTEXT, R0)) / sizeof(ULONGLONG);
#endif
-#if defined(TARGET_ARM) || defined(TARGET_ARM64)
+#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_RISCV64)
BYTE* pContext = (BYTE*)&(pRD->volatileCurrContextPointers);
#elif defined(TARGET_LOONGARCH64)
assert(!"unimplemented on LOONGARCH yet");
BYTE* pContext = (BYTE*)pRD->pCurrentContext;
-#elif defined(TARGET_RISCV64)
- assert(!"unimplemented on RISCV64 yet");
- // TODO implement risc-v code, that should care about volatile registers (same as arm/arm64 architectures)
- // instead of default code.
- BYTE* pContext = (BYTE*)pRD->pCurrentContext;
#else
BYTE* pContext = (BYTE*)pRD->pCurrentContext;
#endif
@@ -370,7 +364,18 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
#elif defined(TARGET_LOONGARCH64)
assert(!"unimplemented on LOONGARCH yet");
#elif defined(TARGET_RISCV64)
- assert(!"unimplemented on RISCV64 yet");
+ bool isVolatile = (iReg == 0 || (iReg >= 5 && iReg <= 7) || (iReg >= 10 && iReg <= 17) || iReg >= 28);
+ if (ctx == 0)
+ {
+ if (!isVolatile)
+ {
+ continue;
+ }
+ }
+ else if (isVolatile) // skip volatile registers for second context
+ {
+ continue;
+ }
#endif
{
_ASSERTE(iReg < nCONTEXTRegisters);
@@ -389,7 +394,7 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
pReg = *(SIZE_T**)((BYTE*)pRD->pCurrentContextPointers + rgRegisters[iEncodedReg].cbContextOffset);
}
-#elif defined(TARGET_ARM64)
+#elif defined(TARGET_ARM64) || defined(TARGET_RISCV64)
pReg = *(SIZE_T**)(pContext + rgRegisters[iReg].cbContextOffset);
if (iEncodedReg == iSPRegister)
{
@@ -398,11 +403,6 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
#elif defined(TARGET_LOONGARCH64)
assert(!"unimplemented on LOONGARCH yet");
pReg = (SIZE_T*)(pContext + rgRegisters[iReg].cbContextOffset);
-#elif defined(TARGET_RISCV64)
- assert(!"unimplemented on RISCV64 yet");
- // TODO implement risc-v code, that should care about volatile registers (same as arm/arm64 architectures)
- // instead of default code.
- pReg = (SIZE_T*)(pContext + rgRegisters[iReg].cbContextOffset);
#else
pReg = (SIZE_T*)(pContext + rgRegisters[iReg].cbContextOffset);
#endif
@@ -470,26 +470,18 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
GcStackSlotBase base;
if (iSPRegister == iEncodedReg)
{
-#if defined(TARGET_ARM) || defined(TARGET_ARM64)
+#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_RISCV64)
base = GC_SP_REL;
#elif defined(TARGET_LOONGARCH64)
assert(!"unimplemented on LOONGARCH yet");
//TODO: should confirm ?
base = GC_SP_REL;
-#elif defined(TARGET_RISCV64)
- assert(!"unimplemented on RISCV64 yet");
- // TODO implement risc-v code, that should care about volatile registers (same as arm/arm64 architectures)
- // instead of default code.
- if (0 == ctx)
- base = GC_SP_REL;
- else
- base = GC_CALLER_SP_REL;
#else
if (0 == ctx)
base = GC_SP_REL;
else
base = GC_CALLER_SP_REL;
-#endif //defined(TARGET_ARM) || defined(TARGET_ARM64)
+#endif //defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_RISCV64)
}
else
{
@@ -511,15 +503,10 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
}
}
-#if defined(TARGET_ARM) || defined(TARGET_ARM64)
+#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_RISCV64)
pContext = (BYTE*)pRD->pCurrentContextPointers;
#elif defined(TARGET_LOONGARCH64)
assert(!"unimplemented on LOONGARCH yet");
-#elif defined(TARGET_RISCV64)
- assert(!"unimplemented on RISCV64 yet");
- // TODO implement risc-v code, that should care about volatile registers (same as arm/arm64 architectures)
- // instead of default code.
- pContext = (BYTE*)pRD->pCallerContext;
#else
pContext = (BYTE*)pRD->pCallerContext;
#endif
@@ -846,14 +833,11 @@ PORTABILITY_ASSERT("GcInfoDumper::EnumerateStateChanges is not implemented on th
#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
UINT32 safePointOffset = offset;
-#if defined(TARGET_AMD64) || defined(TARGET_ARM) || defined(TARGET_ARM64)
+#if defined(TARGET_AMD64) || defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_RISCV64)
safePointOffset++;
#elif defined(TARGET_LOONGARCH64)
#pragma message("Unimplemented for LOONGARCH64 yet.")
assert(!"unimplemented on LOONGARCH yet");
-#elif defined(TARGET_RISCV64)
-#pragma message("Unimplemented for RISCV64 yet.")
- assert(!"unimplemented on RISCV64 yet");
#endif
if(safePointDecoder.IsSafePoint(safePointOffset))
{
diff --git a/src/coreclr/ilasm/assembler.cpp b/src/coreclr/ilasm/assembler.cpp
index e105c00162c55..4aa33378c0838 100644
--- a/src/coreclr/ilasm/assembler.cpp
+++ b/src/coreclr/ilasm/assembler.cpp
@@ -1420,6 +1420,15 @@ void Assembler::EmitOpcode(Instr* instr)
pLPC->PC = m_CurPC;
pLPC->pOwnerDocument = instr->pOwnerDocument;
+ if(m_pCurMethod->m_FirstDocument == NULL)
+ {
+ m_pCurMethod->m_FirstDocument = instr->pOwnerDocument;
+ }
+ else if (instr->pOwnerDocument != NULL && m_pCurMethod->m_FirstDocument != instr->pOwnerDocument)
+ {
+ m_pCurMethod->m_HasMultipleDocuments = TRUE;
+ }
+
if (0xfeefee == instr->linenum &&
0xfeefee == instr->linenum_end &&
0 == instr->column &&
diff --git a/src/coreclr/ilasm/method.cpp b/src/coreclr/ilasm/method.cpp
index c8946e7f80d78..7fb5767b3bd2f 100644
--- a/src/coreclr/ilasm/method.cpp
+++ b/src/coreclr/ilasm/method.cpp
@@ -35,6 +35,8 @@ Method::Method(Assembler *pAssembler, Class *pClass, _In_ __nullterminated char
m_pbsBody = NULL;
m_fNewBody = TRUE;
m_fNew = TRUE;
+ m_FirstDocument = NULL;
+ m_HasMultipleDocuments = FALSE;
// move the PInvoke descriptor (if any) from Assembler
// (Assembler gets the descriptor BEFORE it calls new Method)
diff --git a/src/coreclr/ilasm/method.hpp b/src/coreclr/ilasm/method.hpp
index 4af091a0c5dcd..8a0a1fd87293b 100644
--- a/src/coreclr/ilasm/method.hpp
+++ b/src/coreclr/ilasm/method.hpp
@@ -337,6 +337,8 @@ class Method
unsigned m_LineNum;
// debug info
LinePCList m_LinePCList;
+ Document* m_FirstDocument;
+ BOOL m_HasMultipleDocuments;
// custom values
CustomDescrList m_CustomDescrList;
// token relocs (used for OBJ generation only)
diff --git a/src/coreclr/ilasm/portable_pdb.cpp b/src/coreclr/ilasm/portable_pdb.cpp
index 5e56e55eb716e..68bd1bd72b950 100644
--- a/src/coreclr/ilasm/portable_pdb.cpp
+++ b/src/coreclr/ilasm/portable_pdb.cpp
@@ -209,6 +209,7 @@ HRESULT PortablePdbWriter::DefineSequencePoints(Method* method)
ULONG localSigRid = 0;
ULONG offset = 0;
ULONG deltaLines = 0;
+ ULONG currDocumentRid = 0;
LONG deltaColumns = 0;
LONG deltaStartLine = 0;
LONG deltaStartColumn = 0;
@@ -225,7 +226,11 @@ HRESULT PortablePdbWriter::DefineSequencePoints(Method* method)
// LocalSignature
localSigRid = RidFromToken(method->m_LocalsSig);
CompressUnsignedLong(localSigRid, blob);
- // InitialDocument TODO: skip this for now
+ currDocumentRid = RidFromToken(method->m_FirstDocument->GetToken());
+ if(method->m_HasMultipleDocuments)
+ {
+ CompressUnsignedLong(currDocumentRid, blob);
+ }
}
// SequencePointRecord :: = sequence-point-record | hidden-sequence-point-record
@@ -250,6 +255,15 @@ HRESULT PortablePdbWriter::DefineSequencePoints(Method* method)
if (!currSeqPoint->IsHidden)
{
+ //document
+ if(RidFromToken(currSeqPoint->pOwnerDocument->GetToken()) != currDocumentRid)
+ {
+ //document-record
+ currDocumentRid = RidFromToken(currSeqPoint->pOwnerDocument->GetToken());
+ CompressUnsignedLong(0, blob);
+ CompressUnsignedLong(currDocumentRid, blob);
+ }
+
//offset
offset = (i == 0) ? currSeqPoint->PC : currSeqPoint->PC - prevSeqPoint->PC;
CompressUnsignedLong(offset, blob);
@@ -311,8 +325,8 @@ HRESULT PortablePdbWriter::DefineSequencePoints(Method* method)
// finally define sequence points for the method
if ((isValid && currSeqPoint != NULL) || hasEmptyMethodBody)
{
- mdDocument document = hasEmptyMethodBody ? m_currentDocument->GetToken() : currSeqPoint->pOwnerDocument->GetToken();
- ULONG documentRid = RidFromToken(document);
+ mdDocument document = hasEmptyMethodBody ? m_currentDocument->GetToken() : method->m_FirstDocument->GetToken();
+ ULONG documentRid = method->m_HasMultipleDocuments ? 0 : RidFromToken(document);
hr = m_pdbEmitter->DefineSequencePoints(documentRid, blob->ptr(), blob->length());
}
diff --git a/src/coreclr/inc/check.h b/src/coreclr/inc/check.h
index 30ea0fdaf4d81..4e8a6fd42307a 100644
--- a/src/coreclr/inc/check.h
+++ b/src/coreclr/inc/check.h
@@ -8,7 +8,6 @@
// Assertion checking infrastructure
// ---------------------------------------------------------------------------
-
#ifndef CHECK_H_
#define CHECK_H_
@@ -16,6 +15,18 @@
#include "daccess.h"
#include "unreachable.h"
+// Use the C++ detection idiom (https://isocpp.org/blog/2017/09/detection-idiom-a-stopgap-for-concepts-simon-brand)
+template struct make_void { using type = void; };
+template using void_t = typename make_void::type;
+
+// Macros for creating type traits to check if a member exists
+#define DEFINE_MEMBER_EXISTENCE_CHECK(Member) \
+template \
+struct has_##Member : std::false_type {}; \
+\
+template \
+struct has_##Member().Member)>> : std::true_type {};
+
#ifdef _DEBUG
#ifdef _MSC_VER
@@ -282,19 +293,34 @@ do \
#if CHECK_INVARIANTS
+DEFINE_MEMBER_EXISTENCE_CHECK(Invariant);
+DEFINE_MEMBER_EXISTENCE_CHECK(InternalInvariant);
+
+template
+typename std::enable_if::value, CHECK>::type CheckInvariantOnly(TYPENAME &obj)
+{
+ CHECK(obj.Invariant());
+ CHECK_OK;
+}
+
+template
+typename std::enable_if::value, CHECK>::type CheckInvariantOnly(TYPENAME &obj) { CHECK_OK; }
+
+template
+typename std::enable_if::value, CHECK>::type CheckInternalInvariantOnly(TYPENAME &obj)
+{
+ CHECK(obj.InternalInvariant());
+ CHECK_OK;
+}
+
+template
+typename std::enable_if::value, CHECK>::type CheckInternalInvariantOnly(TYPENAME &obj) { CHECK_OK; }
+
template
CHECK CheckInvariant(TYPENAME &obj)
{
-#if defined(_MSC_VER) || defined(__llvm__)
- __if_exists(TYPENAME::Invariant)
- {
- CHECK(obj.Invariant());
- }
- __if_exists(TYPENAME::InternalInvariant)
- {
- CHECK(obj.InternalInvariant());
- }
-#endif
+ CheckInvariantOnly(obj);
+ CheckInternalInvariantOnly(obj);
CHECK_OK;
}
@@ -331,8 +357,9 @@ enum IsNullOK
};
#if CHECK_INVARIANTS
+DEFINE_MEMBER_EXISTENCE_CHECK(Check);
template
-CHECK CheckPointer(TYPENAME *o, IsNullOK ok = NULL_NOT_OK)
+typename std::enable_if::value, CHECK>::type CheckPointer(TYPENAME *o, IsNullOK ok = NULL_NOT_OK)
{
if (o == NULL)
{
@@ -340,29 +367,35 @@ CHECK CheckPointer(TYPENAME *o, IsNullOK ok = NULL_NOT_OK)
}
else
{
-#if defined(_MSC_VER) || defined(__llvm__)
- __if_exists(TYPENAME::Check)
- {
- CHECK(o->Check());
- }
-#endif
+ CHECK(o->Check());
}
CHECK_OK;
}
template
-CHECK CheckValue(TYPENAME &val)
+typename std::enable_if::value, CHECK>::type CheckPointer(TYPENAME *o, IsNullOK ok = NULL_NOT_OK)
{
-#if defined(_MSC_VER) || defined(__llvm__)
- __if_exists(TYPENAME::Check)
+ if (o == NULL)
{
- CHECK(val.Check());
+ CHECK_MSG(ok, "Illegal null pointer");
}
-#endif
+ CHECK_OK;
+}
+
+template
+typename std::enable_if::value, CHECK>::type CheckValue(TYPENAME &val)
+{
+ CHECK(val.Check());
CHECK(CheckInvariant(val));
+ CHECK_OK;
+}
+template
+typename std::enable_if::value, CHECK>::type CheckValue(TYPENAME &val)
+{
+ CHECK(CheckInvariant(val));
CHECK_OK;
}
#else // CHECK_INVARIANTS
diff --git a/src/coreclr/inc/iterator.h b/src/coreclr/inc/iterator.h
index b7bb142665c46..df50ca948eed0 100644
--- a/src/coreclr/inc/iterator.h
+++ b/src/coreclr/inc/iterator.h
@@ -201,9 +201,9 @@ class IndexerBasePrototype
SCOUNT_T Subtract(const IndexerBasePrototype &i) const;
CHECK DoCheck(SCOUNT_T delta) const;
};
-
};
+DEFINE_MEMBER_EXISTENCE_CHECK(m_revision);
template
class CheckedIteratorBase
@@ -214,20 +214,21 @@ class CheckedIteratorBase
int m_revision;
#endif
- CHECK CheckRevision() const
+ template
+ typename std::enable_if::value, CHECK>::type CheckRevision() const
{
LIMITED_METHOD_CONTRACT;
SUPPORTS_DAC;
-#if defined(_DEBUG) && (defined(_MSC_VER) || defined(__llvm__))
- __if_exists(CONTAINER::m_revision)
- {
- CHECK_MSG(m_revision == m_container->m_revision,
- "Use of Iterator after container has been modified");
- }
+#if defined(_DEBUG)
+ CHECK_MSG(m_revision == m_container->m_revision,
+ "Use of Iterator after container has been modified");
#endif
CHECK_OK;
}
+ template
+ typename std::enable_if::value, CHECK>::type CheckRevision() const { CHECK_OK; }
+
CheckedIteratorBase()
{
LIMITED_METHOD_DAC_CONTRACT;
@@ -238,30 +239,34 @@ class CheckedIteratorBase
CheckedIteratorBase(const CONTAINER *container)
{
- LIMITED_METHOD_CONTRACT;
#if defined(_DEBUG)
m_container = container;
-#if defined(_MSC_VER) || defined(__llvm__)
- __if_exists(CONTAINER::m_revision)
- {
- m_revision = m_container->m_revision;
- }
+ Init(container, has_m_revision());
#endif
+ }
+
+ void Init(const CONTAINER *container, std::true_type)
+ {
+#if defined(_DEBUG)
+ m_revision = container->m_revision;
#endif
}
- void Resync(const CONTAINER *container)
+ void Init(const CONTAINER *container, std::false_type) { /* No-op */ }
+
+ template
+ typename std::enable_if::value, void>::type Resync(const CONTAINER *container)
{
LIMITED_METHOD_DAC_CONTRACT;
-#if defined(_DEBUG) && (defined(_MSC_VER) || defined(__llvm__))
- __if_exists(CONTAINER::m_revision)
- {
- m_revision = m_container->m_revision;
- }
+#if defined(_DEBUG)
+ m_revision = m_container->m_revision;
#endif
}
+ template
+ typename std::enable_if::value, void>::type Resync(const CONTAINER *container) { /* No-op */ }
+
#if defined(_DEBUG)
const CONTAINER *GetContainerDebug() const
{
diff --git a/src/coreclr/inc/slist.h b/src/coreclr/inc/slist.h
index 805413fd3da34..e48a078adda5d 100644
--- a/src/coreclr/inc/slist.h
+++ b/src/coreclr/inc/slist.h
@@ -26,6 +26,8 @@
#ifndef _H_SLIST_
#define _H_SLIST_
+#include "cdacoffsets.h"
+
//------------------------------------------------------------------
// struct SLink, to use a singly linked list
// have a data member m_Link of type SLink in your class
@@ -118,6 +120,8 @@ class SList
PTR_SLink m_pHead;
PTR_SLink m_pTail;
+ template friend struct ::cdac_offsets;
+
// get the list node within the object
static SLink* GetLink (T* pLink)
{
diff --git a/src/coreclr/inc/utilcode.h b/src/coreclr/inc/utilcode.h
index 53e4b2bb0fe97..23680253c70ae 100644
--- a/src/coreclr/inc/utilcode.h
+++ b/src/coreclr/inc/utilcode.h
@@ -166,6 +166,12 @@ typedef LPSTR LPUTF8;
#define DEBUGARG(x)
#endif
+#if defined(FEATURE_READYTORUN)
+#define R2RARG(x) , x
+#else
+#define R2RARG(x)
+#endif
+
#ifndef sizeofmember
// Returns the size of a class or struct member.
#define sizeofmember(c,m) (sizeof(((c*)0)->m))
diff --git a/src/coreclr/interop/comwrappers.hpp b/src/coreclr/interop/comwrappers.hpp
index ac120d2abb783..47bf008ac5012 100644
--- a/src/coreclr/interop/comwrappers.hpp
+++ b/src/coreclr/interop/comwrappers.hpp
@@ -231,7 +231,7 @@ class TrackerObjectManager
};
// Class used to hold COM objects (i.e. IUnknown base class)
-// This class mimics the semantics of ATL::CComPtr (https://docs.microsoft.com/cpp/atl/reference/ccomptr-class).
+// This class mimics the semantics of ATL::CComPtr (https://learn.microsoft.com/cpp/atl/reference/ccomptr-class).
template
struct ComHolder
{
diff --git a/src/coreclr/interop/inc/interoplib.h b/src/coreclr/interop/inc/interoplib.h
index 37237f5f7cab3..684283b7133bd 100644
--- a/src/coreclr/interop/inc/interoplib.h
+++ b/src/coreclr/interop/inc/interoplib.h
@@ -52,7 +52,7 @@ namespace InteropLib
// The returned context memory is guaranteed to be initialized to zero.
void* Context;
- // See https://docs.microsoft.com/windows/win32/api/windows.ui.xaml.hosting.referencetracker/
+ // See https://learn.microsoft.com/windows/win32/api/windows.ui.xaml.hosting.referencetracker/
// for details.
bool FromTrackerRuntime;
diff --git a/src/coreclr/interop/referencetrackertypes.hpp b/src/coreclr/interop/referencetrackertypes.hpp
index 239503e544d93..ff4d8b84ac20c 100644
--- a/src/coreclr/interop/referencetrackertypes.hpp
+++ b/src/coreclr/interop/referencetrackertypes.hpp
@@ -6,7 +6,7 @@
#include
-// Documentation found at https://docs.microsoft.com/windows/win32/api/windows.ui.xaml.hosting.referencetracker/
+// Documentation found at https://learn.microsoft.com/windows/win32/api/windows.ui.xaml.hosting.referencetracker/
// 64bd43f8-bfee-4ec4-b7eb-2935158dae21
const GUID IID_IReferenceTrackerTarget = { 0x64bd43f8, 0xbfee, 0x4ec4, { 0xb7, 0xeb, 0x29, 0x35, 0x15, 0x8d, 0xae, 0x21 } };
diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp
index 6d72657fd97f6..7f41f0ae7ac64 100644
--- a/src/coreclr/jit/assertionprop.cpp
+++ b/src/coreclr/jit/assertionprop.cpp
@@ -3128,6 +3128,10 @@ bool Compiler::optIsProfitableToSubstitute(GenTree* dest, BasicBlock* destBlock,
return false;
}
+ // For several of the scenarios below we may skip the costing logic
+ // since we know that the operand is always containable and therefore
+ // is always cost effective to propagate.
+
switch (intrinsicId)
{
#if defined(TARGET_ARM64)
@@ -3144,13 +3148,8 @@ bool Compiler::optIsProfitableToSubstitute(GenTree* dest, BasicBlock* destBlock,
#endif // TARGET_XARCH
{
// We can optimize when the constant is zero, but only
- // for non floating-point since +0.0 == -0.0
-
- if (!vecCon->IsZero() || varTypeIsFloating(simdBaseType))
- {
- return false;
- }
- break;
+ // for non floating-point since +0.0 == -0.0.
+ return vecCon->IsZero() && !varTypeIsFloating(simdBaseType);
}
#if defined(TARGET_ARM64)
@@ -3160,12 +3159,7 @@ bool Compiler::optIsProfitableToSubstitute(GenTree* dest, BasicBlock* destBlock,
{
// We can optimize when the constant is zero due to a
// specialized encoding for the instruction
-
- if (!vecCon->IsZero())
- {
- return false;
- }
- break;
+ return vecCon->IsZero();
}
case NI_AdvSimd_CompareGreaterThan:
@@ -3178,28 +3172,16 @@ bool Compiler::optIsProfitableToSubstitute(GenTree* dest, BasicBlock* destBlock,
// We can optimize when the constant is zero, but only
// for signed types, due to a specialized encoding for
// the instruction
-
- if (!vecCon->IsZero() || varTypeIsUnsigned(simdBaseType))
- {
- return false;
- }
- break;
+ return vecCon->IsZero() && !varTypeIsUnsigned(simdBaseType);
}
#endif // TARGET_ARM64
#if defined(TARGET_XARCH)
- case NI_SSE2_Insert:
case NI_SSE41_Insert:
- case NI_SSE41_X64_Insert:
{
// We can optimize for float when the constant is zero
// due to a specialized encoding for the instruction
-
- if ((simdBaseType != TYP_FLOAT) || !vecCon->IsZero())
- {
- return false;
- }
- break;
+ return (simdBaseType == TYP_FLOAT) && vecCon->IsZero();
}
case NI_AVX512F_CompareEqualMask:
@@ -3207,15 +3189,24 @@ bool Compiler::optIsProfitableToSubstitute(GenTree* dest, BasicBlock* destBlock,
{
// We can optimize when the constant is zero, but only
// for non floating-point since +0.0 == -0.0
-
- if (!vecCon->IsZero() || varTypeIsFloating(simdBaseType))
- {
- return false;
- }
- break;
+ return vecCon->IsZero() && !varTypeIsFloating(simdBaseType);
}
#endif // TARGET_XARCH
+ case NI_Vector128_Shuffle:
+#if defined(TARGET_XARCH)
+ case NI_Vector256_Shuffle:
+ case NI_Vector512_Shuffle:
+#elif defined(TARGET_ARM64)
+ case NI_Vector64_Shuffle:
+#endif
+ {
+ // The shuffle indices need to be constant so we can preserve
+ // the node as a hwintrinsic instead of rewriting as a user call.
+ assert(parent->GetOperandCount() == 2);
+ return parent->IsUserCall() && (dest == parent->Op(2));
+ }
+
default:
{
break;
diff --git a/src/coreclr/jit/clrjit.natvis b/src/coreclr/jit/clrjit.natvis
index cfbc6a181e974..485d0c5df5fff 100644
--- a/src/coreclr/jit/clrjit.natvis
+++ b/src/coreclr/jit/clrjit.natvis
@@ -8,8 +8,8 @@ The .NET Foundation licenses this file to you under the MIT license.
diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h
index 2262fe3d9e2de..5130c79983241 100644
--- a/src/coreclr/jit/codegen.h
+++ b/src/coreclr/jit/codegen.h
@@ -994,7 +994,10 @@ class CodeGen final : public CodeGenInterface
class HWIntrinsicImmOpHelper final
{
public:
- HWIntrinsicImmOpHelper(CodeGen* codeGen, GenTree* immOp, GenTreeHWIntrinsic* intrin, int immNum = 1);
+ HWIntrinsicImmOpHelper(CodeGen* codeGen, GenTree* immOp, GenTreeHWIntrinsic* intrin);
+
+ HWIntrinsicImmOpHelper(
+ CodeGen* codeGen, regNumber immReg, int immLowerBound, int immUpperBound, GenTreeHWIntrinsic* intrin);
void EmitBegin();
void EmitCaseEnd();
@@ -1040,6 +1043,7 @@ class CodeGen final : public CodeGenInterface
regNumber nonConstImmReg;
regNumber branchTargetReg;
};
+
#endif // TARGET_ARM64
#endif // FEATURE_HW_INTRINSICS
diff --git a/src/coreclr/jit/codegenarm64test.cpp b/src/coreclr/jit/codegenarm64test.cpp
index b2328b7df04bb..a85b2c6d0f941 100644
--- a/src/coreclr/jit/codegenarm64test.cpp
+++ b/src/coreclr/jit/codegenarm64test.cpp
@@ -5067,7 +5067,7 @@ void CodeGen::genArm64EmitterUnitTestsSve()
theEmitter->emitIns_R_R(INS_sve_ptest, EA_SCALABLE, REG_P2, REG_P14, INS_OPTS_SCALABLE_B); // PTEST , .B
// IF_SVE_DK_3A
- theEmitter->emitIns_R_R_R(INS_sve_cntp, EA_8BYTE, REG_R29, REG_P0, REG_P15,
+ theEmitter->emitIns_R_R_R(INS_sve_cntp, EA_SCALABLE, REG_R29, REG_P0, REG_P15,
INS_OPTS_SCALABLE_D); // CNTP , , .
// IF_SVE_GE_4A
@@ -6351,21 +6351,21 @@ void CodeGen::genArm64EmitterUnitTestsSve()
INS_OPTS_SCALABLE_B); // UQSHRNT ., ., #
// IF_SVE_DL_2A
- theEmitter->emitIns_R_R(INS_sve_cntp, EA_8BYTE, REG_R0, REG_P0, INS_OPTS_SCALABLE_B,
+ theEmitter->emitIns_R_R(INS_sve_cntp, EA_SCALABLE, REG_R0, REG_P0, INS_OPTS_SCALABLE_B,
INS_SCALABLE_OPTS_VL_2X); // CNTP , .,
- theEmitter->emitIns_R_R(INS_sve_cntp, EA_8BYTE, REG_R1, REG_P1, INS_OPTS_SCALABLE_B,
+ theEmitter->emitIns_R_R(INS_sve_cntp, EA_SCALABLE, REG_R1, REG_P1, INS_OPTS_SCALABLE_B,
INS_SCALABLE_OPTS_VL_4X); // CNTP , .,
- theEmitter->emitIns_R_R(INS_sve_cntp, EA_8BYTE, REG_R2, REG_P2, INS_OPTS_SCALABLE_H,
+ theEmitter->emitIns_R_R(INS_sve_cntp, EA_SCALABLE, REG_R2, REG_P2, INS_OPTS_SCALABLE_H,
INS_SCALABLE_OPTS_VL_2X); // CNTP , .,
- theEmitter->emitIns_R_R(INS_sve_cntp, EA_8BYTE, REG_R3, REG_P3, INS_OPTS_SCALABLE_H,
+ theEmitter->emitIns_R_R(INS_sve_cntp, EA_SCALABLE, REG_R3, REG_P3, INS_OPTS_SCALABLE_H,
INS_SCALABLE_OPTS_VL_4X); // CNTP , .,
- theEmitter->emitIns_R_R(INS_sve_cntp, EA_8BYTE, REG_R4, REG_P4, INS_OPTS_SCALABLE_S,
+ theEmitter->emitIns_R_R(INS_sve_cntp, EA_SCALABLE, REG_R4, REG_P4, INS_OPTS_SCALABLE_S,
INS_SCALABLE_OPTS_VL_2X); // CNTP , .,
- theEmitter->emitIns_R_R(INS_sve_cntp, EA_8BYTE, REG_R5, REG_P5, INS_OPTS_SCALABLE_S,
+ theEmitter->emitIns_R_R(INS_sve_cntp, EA_SCALABLE, REG_R5, REG_P5, INS_OPTS_SCALABLE_S,
INS_SCALABLE_OPTS_VL_4X); // CNTP , .,
- theEmitter->emitIns_R_R(INS_sve_cntp, EA_8BYTE, REG_R6, REG_P6, INS_OPTS_SCALABLE_D,
+ theEmitter->emitIns_R_R(INS_sve_cntp, EA_SCALABLE, REG_R6, REG_P6, INS_OPTS_SCALABLE_D,
INS_SCALABLE_OPTS_VL_2X); // CNTP , .,
- theEmitter->emitIns_R_R(INS_sve_cntp, EA_8BYTE, REG_R7, REG_P7, INS_OPTS_SCALABLE_D,
+ theEmitter->emitIns_R_R(INS_sve_cntp, EA_SCALABLE, REG_R7, REG_P7, INS_OPTS_SCALABLE_D,
INS_SCALABLE_OPTS_VL_4X); // CNTP , .,
// IF_SVE_DM_2A
diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp
index a2ac6832d8222..ebf6bd7fc9908 100644
--- a/src/coreclr/jit/codegencommon.cpp
+++ b/src/coreclr/jit/codegencommon.cpp
@@ -584,7 +584,7 @@ void CodeGenInterface::genUpdateLife(VARSET_VALARG_TP newLife)
// inline
regMaskTP CodeGenInterface::genGetRegMask(const LclVarDsc* varDsc)
{
- regMaskTP regMask = RBM_NONE;
+ regMaskTP regMask;
assert(varDsc->lvIsInReg());
@@ -3491,8 +3491,12 @@ void CodeGen::genHomeRegisterParams(regNumber initReg, bool* initRegStillZeroed)
//
regMaskTP CodeGen::genGetParameterHomingTempRegisterCandidates()
{
- return RBM_CALLEE_TRASH | intRegState.rsCalleeRegArgMaskLiveIn | floatRegState.rsCalleeRegArgMaskLiveIn |
- regSet.rsGetModifiedRegsMask();
+ regMaskTP regs = RBM_CALLEE_TRASH | intRegState.rsCalleeRegArgMaskLiveIn | floatRegState.rsCalleeRegArgMaskLiveIn |
+ regSet.rsGetModifiedRegsMask();
+ // We may have reserved register that the backend needs to access stack
+ // locals. We cannot place state in that register.
+ regs &= ~regSet.rsMaskResvd;
+ return regs;
}
/*****************************************************************************
@@ -4828,7 +4832,7 @@ void CodeGen::genFinalizeFrame()
regMaskTP homingCandidates = genGetParameterHomingTempRegisterCandidates();
if (((homingCandidates & ~intRegState.rsCalleeRegArgMaskLiveIn) & RBM_ALLINT) == RBM_NONE)
{
- regMaskTP extraRegMask = RBM_ALLINT & ~homingCandidates;
+ regMaskTP extraRegMask = RBM_ALLINT & ~homingCandidates & ~regSet.rsMaskResvd;
assert(extraRegMask != RBM_NONE);
regNumber extraReg = genFirstRegNumFromMask(extraRegMask);
JITDUMP("No temporary registers are available for integer parameter homing. Adding %s\n", getRegName(extraReg));
@@ -4837,7 +4841,7 @@ void CodeGen::genFinalizeFrame()
if (((homingCandidates & ~floatRegState.rsCalleeRegArgMaskLiveIn) & RBM_ALLFLOAT) == RBM_NONE)
{
- regMaskTP extraRegMask = RBM_ALLFLOAT & ~homingCandidates;
+ regMaskTP extraRegMask = RBM_ALLFLOAT & ~homingCandidates & ~regSet.rsMaskResvd;
assert(extraRegMask != RBM_NONE);
regNumber extraReg = genFirstRegNumFromMask(extraRegMask);
JITDUMP("No temporary registers are available for float parameter homing. Adding %s\n", getRegName(extraReg));
diff --git a/src/coreclr/jit/codegeninterface.h b/src/coreclr/jit/codegeninterface.h
index a025285cbc091..608c72c22d48d 100644
--- a/src/coreclr/jit/codegeninterface.h
+++ b/src/coreclr/jit/codegeninterface.h
@@ -75,31 +75,31 @@ class CodeGenInterface
}
#if defined(TARGET_AMD64)
- SingleTypeRegSet rbmAllFloat;
- SingleTypeRegSet rbmFltCalleeTrash;
+ regMaskTP rbmAllFloat;
+ regMaskTP rbmFltCalleeTrash;
- FORCEINLINE SingleTypeRegSet get_RBM_ALLFLOAT() const
+ FORCEINLINE regMaskTP get_RBM_ALLFLOAT() const
{
return this->rbmAllFloat;
}
- FORCEINLINE SingleTypeRegSet get_RBM_FLT_CALLEE_TRASH() const
+ FORCEINLINE regMaskTP get_RBM_FLT_CALLEE_TRASH() const
{
return this->rbmFltCalleeTrash;
}
#endif // TARGET_AMD64
#if defined(TARGET_XARCH)
- SingleTypeRegSet rbmAllMask;
- SingleTypeRegSet rbmMskCalleeTrash;
+ regMaskTP rbmAllMask;
+ regMaskTP rbmMskCalleeTrash;
// Call this function after the equivalent fields in Compiler have been initialized.
void CopyRegisterInfo();
- FORCEINLINE SingleTypeRegSet get_RBM_ALLMASK() const
+ FORCEINLINE regMaskTP get_RBM_ALLMASK() const
{
return this->rbmAllMask;
}
- FORCEINLINE SingleTypeRegSet get_RBM_MSK_CALLEE_TRASH() const
+ FORCEINLINE regMaskTP get_RBM_MSK_CALLEE_TRASH() const
{
return this->rbmMskCalleeTrash;
}
diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp
index 64c2b84e87b43..757491b95034d 100644
--- a/src/coreclr/jit/codegenxarch.cpp
+++ b/src/coreclr/jit/codegenxarch.cpp
@@ -9912,7 +9912,7 @@ void CodeGen::genFnEpilog(BasicBlock* block)
// if we reported the frame pointer in the prolog. The Windows x64 unwinding ABI specifically
// disallows this `lea` form:
//
- // See https://docs.microsoft.com/en-us/cpp/build/prolog-and-epilog?view=msvc-160#epilog-code
+ // See https://learn.microsoft.com/cpp/build/prolog-and-epilog?view=msvc-160#epilog-code
//
// "When a frame pointer is not used, the epilog must use add RSP,constant to deallocate the fixed part of the
// stack. It may not use lea RSP,constant[RSP] instead. This restriction exists so the unwind code has fewer
diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp
index 1b5592a5b59e5..54be15ed7f20b 100644
--- a/src/coreclr/jit/compiler.cpp
+++ b/src/coreclr/jit/compiler.cpp
@@ -3485,12 +3485,12 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
// Make sure we copy the register info and initialize the
// trash regs after the underlying fields are initialized
- const SingleTypeRegSet vtCalleeTrashRegs[TYP_COUNT]{
+ const regMaskTP vtCalleeTrashRegs[TYP_COUNT]{
#define DEF_TP(tn, nm, jitType, sz, sze, asze, st, al, regTyp, regFld, csr, ctr, tf) ctr,
#include "typelist.h"
#undef DEF_TP
};
- memcpy(varTypeCalleeTrashRegs, vtCalleeTrashRegs, sizeof(SingleTypeRegSet) * TYP_COUNT);
+ memcpy(varTypeCalleeTrashRegs, vtCalleeTrashRegs, sizeof(regMaskTP) * TYP_COUNT);
codeGen->CopyRegisterInfo();
#endif // TARGET_XARCH
diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h
index 428c817c751c7..9281f55471ec7 100644
--- a/src/coreclr/jit/compiler.h
+++ b/src/coreclr/jit/compiler.h
@@ -72,22 +72,21 @@ inline var_types genActualType(T value);
* Forward declarations
*/
-struct InfoHdr; // defined in GCInfo.h
-struct escapeMapping_t; // defined in fgdiagnostic.cpp
-class emitter; // defined in emit.h
-struct ShadowParamVarInfo; // defined in GSChecks.cpp
-struct InitVarDscInfo; // defined in registerargconvention.h
-class FgStack; // defined in fgbasic.cpp
-class Instrumentor; // defined in fgprofile.cpp
-class SpanningTreeVisitor; // defined in fgprofile.cpp
-class CSE_DataFlow; // defined in optcse.cpp
-struct CSEdsc; // defined in optcse.h
-class CSE_HeuristicCommon; // defined in optcse.h
-class OptBoolsDsc; // defined in optimizer.cpp
-struct RelopImplicationInfo; // defined in redundantbranchopts.cpp
-struct JumpThreadInfo; // defined in redundantbranchopts.cpp
-class ProfileSynthesis; // defined in profilesynthesis.h
-class LoopLocalOccurrences; // defined in inductionvariableopts.cpp
+struct InfoHdr; // defined in GCInfo.h
+struct escapeMapping_t; // defined in fgdiagnostic.cpp
+class emitter; // defined in emit.h
+struct ShadowParamVarInfo; // defined in GSChecks.cpp
+struct InitVarDscInfo; // defined in registerargconvention.h
+class FgStack; // defined in fgbasic.cpp
+class Instrumentor; // defined in fgprofile.cpp
+class SpanningTreeVisitor; // defined in fgprofile.cpp
+class CSE_DataFlow; // defined in optcse.cpp
+struct CSEdsc; // defined in optcse.h
+class CSE_HeuristicCommon; // defined in optcse.h
+class OptBoolsDsc; // defined in optimizer.cpp
+struct JumpThreadInfo; // defined in redundantbranchopts.cpp
+class ProfileSynthesis; // defined in profilesynthesis.h
+class LoopLocalOccurrences; // defined in inductionvariableopts.cpp
#ifdef DEBUG
struct IndentStack;
#endif
@@ -1016,9 +1015,10 @@ class LclVarDsc
regMaskTP lvRegMask() const
{
- regMaskTP regMask = RBM_NONE;
if (GetRegNum() != REG_STK)
{
+ regMaskTP regMask;
+
if (varTypeUsesFloatReg(this))
{
regMask = genRegMaskFloat(GetRegNum() ARM_ARG(TypeGet()));
@@ -1033,8 +1033,12 @@ class LclVarDsc
regMask = genRegMask(GetRegNum());
}
+ return regMask;
+ }
+ else
+ {
+ return RBM_NONE;
}
- return regMask;
}
//-----------------------------------------------------------------------------
@@ -2187,6 +2191,8 @@ class FlowGraphNaturalLoop
return m_exitEdges[index];
}
+ BasicBlock* GetPreheader() const;
+
unsigned GetDepth() const;
bool ContainsBlock(BasicBlock* block);
@@ -2495,6 +2501,30 @@ enum class NodeThreading
LIR, // Nodes are in LIR form (after rationalization)
};
+//------------------------------------------------------------------------
+// RelopImplicationInfo
+//
+// Describes information needed to check for and describe the
+// inferences between two relops.
+//
+struct RelopImplicationInfo
+{
+ // Dominating relop, whose value may be determined by control flow
+ ValueNum domCmpNormVN = ValueNumStore::NoVN;
+ // Dominated relop, whose value we would like to determine
+ ValueNum treeNormVN = ValueNumStore::NoVN;
+ // Relationship between the two relops, if any
+ ValueNumStore::VN_RELATION_KIND vnRelation = ValueNumStore::VN_RELATION_KIND::VRK_Same;
+ // Can we draw an inference?
+ bool canInfer = false;
+ // If canInfer and dominating relop is true, can we infer value of dominated relop?
+ bool canInferFromTrue = true;
+ // If canInfer and dominating relop is false, can we infer value of dominated relop?
+ bool canInferFromFalse = true;
+ // Reverse the sense of the inference
+ bool reverseSense = false;
+};
+
/*
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
@@ -4531,7 +4561,8 @@ class Compiler
bool tailCall,
bool callvirt,
CORINFO_RESOLVED_TOKEN* pContstrainedResolvedToken,
- CORINFO_THIS_TRANSFORM constraintCallThisTransform,
+ CORINFO_THIS_TRANSFORM constraintCallThisTransform
+ R2RARG(CORINFO_CONST_LOOKUP* entryPoint),
NamedIntrinsic* pIntrinsicName,
bool* isSpecialIntrinsic = nullptr);
GenTree* impEstimateIntrinsic(CORINFO_METHOD_HANDLE method,
@@ -4540,7 +4571,8 @@ class Compiler
NamedIntrinsic intrinsicName,
bool mustExpand);
GenTree* impMathIntrinsic(CORINFO_METHOD_HANDLE method,
- CORINFO_SIG_INFO* sig,
+ CORINFO_SIG_INFO* sig
+ R2RARG(CORINFO_CONST_LOOKUP* entryPoint),
var_types callType,
NamedIntrinsic intrinsicName,
bool tailCall);
@@ -4573,10 +4605,13 @@ class Compiler
bool mustExpand);
#ifdef FEATURE_HW_INTRINSICS
+ bool IsValidForShuffle(GenTreeVecCon* vecCon, unsigned simdSize, var_types simdBaseType) const;
+
GenTree* impHWIntrinsic(NamedIntrinsic intrinsic,
CORINFO_CLASS_HANDLE clsHnd,
CORINFO_METHOD_HANDLE method,
- CORINFO_SIG_INFO* sig,
+ CORINFO_SIG_INFO* sig
+ R2RARG(CORINFO_CONST_LOOKUP* entryPoint),
bool mustExpand);
GenTree* impSimdAsHWIntrinsic(NamedIntrinsic intrinsic,
CORINFO_CLASS_HANDLE clsHnd,
@@ -4600,7 +4635,8 @@ class Compiler
GenTree* impSpecialIntrinsic(NamedIntrinsic intrinsic,
CORINFO_CLASS_HANDLE clsHnd,
CORINFO_METHOD_HANDLE method,
- CORINFO_SIG_INFO* sig,
+ CORINFO_SIG_INFO* sig
+ R2RARG(CORINFO_CONST_LOOKUP* entryPoint),
CorInfoType simdBaseJitType,
var_types retType,
unsigned simdSize,
@@ -6756,6 +6792,8 @@ class Compiler
PhaseStatus fgMarkAddressExposedLocals();
void fgSequenceLocals(Statement* stmt);
+ bool fgExposeUnpropagatedLocals(bool propagatedAny, class LocalEqualsLocalAddrAssertions* assertions);
+ void fgExposeLocalsInBitVec(BitVec_ValArg_T bitVec);
PhaseStatus PhysicalPromotion();
@@ -6784,8 +6822,8 @@ class Compiler
public:
bool fgIsBigOffset(size_t offset);
-
bool IsValidLclAddr(unsigned lclNum, unsigned offset);
+ bool IsPotentialGCSafePoint(GenTree* tree) const;
private:
bool fgNeedReturnSpillTemp();
@@ -7521,10 +7559,14 @@ class Compiler
#endif
PhaseStatus optInductionVariables();
- bool optWidenPrimaryIV(FlowGraphNaturalLoop* loop,
- unsigned lclNum,
- ScevAddRec* addRec,
- LoopLocalOccurrences* loopLocals);
+
+ bool optMakeLoopDownwardsCounted(ScalarEvolutionContext& scevContext,
+ FlowGraphNaturalLoop* loop,
+ LoopLocalOccurrences* loopLocals);
+ bool optWidenPrimaryIV(FlowGraphNaturalLoop* loop,
+ unsigned lclNum,
+ ScevAddRec* addRec,
+ LoopLocalOccurrences* loopLocals);
bool optCanSinkWidenedIV(unsigned lclNum, FlowGraphNaturalLoop* loop);
bool optIsIVWideningProfitable(unsigned lclNum,
@@ -10201,6 +10243,7 @@ class Compiler
STRESS_MODE(UNWIND) /* stress unwind info; e.g., create function fragments */ \
STRESS_MODE(OPT_REPEAT) /* stress JitOptRepeat */ \
STRESS_MODE(INITIAL_PARAM_REG) /* Stress initial register assigned to parameters */ \
+ STRESS_MODE(DOWNWARDS_COUNTED_LOOPS) /* Make more loops downwards counted */ \
\
/* After COUNT_VARN, stress level 2 does all of these all the time */ \
\
@@ -11246,8 +11289,8 @@ class Compiler
//
// Users of these values need to define four accessor functions:
//
- // SingleTypeRegSet get_RBM_ALLFLOAT();
- // SingleTypeRegSet get_RBM_FLT_CALLEE_TRASH();
+ // regMaskTP get_RBM_ALLFLOAT();
+ // regMaskTP get_RBM_FLT_CALLEE_TRASH();
// unsigned get_CNT_CALLEE_TRASH_FLOAT();
// unsigned get_AVAILABLE_REG_COUNT();
//
@@ -11256,16 +11299,16 @@ class Compiler
// This was done to avoid polluting all `targetXXX.h` macro definitions with a compiler parameter, where only
// TARGET_AMD64 requires one.
//
- SingleTypeRegSet rbmAllFloat;
- SingleTypeRegSet rbmFltCalleeTrash;
- unsigned cntCalleeTrashFloat;
+ regMaskTP rbmAllFloat;
+ regMaskTP rbmFltCalleeTrash;
+ unsigned cntCalleeTrashFloat;
public:
- FORCEINLINE SingleTypeRegSet get_RBM_ALLFLOAT() const
+ FORCEINLINE regMaskTP get_RBM_ALLFLOAT() const
{
return this->rbmAllFloat;
}
- FORCEINLINE SingleTypeRegSet get_RBM_FLT_CALLEE_TRASH() const
+ FORCEINLINE regMaskTP get_RBM_FLT_CALLEE_TRASH() const
{
return this->rbmFltCalleeTrash;
}
@@ -11284,8 +11327,8 @@ class Compiler
//
// Users of these values need to define four accessor functions:
//
- // SingleTypeRegSet get_RBM_ALLMASK();
- // SingleTypeRegSet get_RBM_MSK_CALLEE_TRASH();
+ // regMaskTP get_RBM_ALLMASK();
+ // regMaskTP get_RBM_MSK_CALLEE_TRASH();
// unsigned get_CNT_CALLEE_TRASH_MASK();
// unsigned get_AVAILABLE_REG_COUNT();
//
@@ -11294,17 +11337,17 @@ class Compiler
// This was done to avoid polluting all `targetXXX.h` macro definitions with a compiler parameter, where only
// TARGET_XARCH requires one.
//
- SingleTypeRegSet rbmAllMask;
- SingleTypeRegSet rbmMskCalleeTrash;
- unsigned cntCalleeTrashMask;
- SingleTypeRegSet varTypeCalleeTrashRegs[TYP_COUNT];
+ regMaskTP rbmAllMask;
+ regMaskTP rbmMskCalleeTrash;
+ unsigned cntCalleeTrashMask;
+ regMaskTP varTypeCalleeTrashRegs[TYP_COUNT];
public:
- FORCEINLINE SingleTypeRegSet get_RBM_ALLMASK() const
+ FORCEINLINE regMaskTP get_RBM_ALLMASK() const
{
return this->rbmAllMask;
}
- FORCEINLINE SingleTypeRegSet get_RBM_MSK_CALLEE_TRASH() const
+ FORCEINLINE regMaskTP get_RBM_MSK_CALLEE_TRASH() const
{
return this->rbmMskCalleeTrash;
}
diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp
index 648e2acc65acd..4c5910d53daca 100644
--- a/src/coreclr/jit/compiler.hpp
+++ b/src/coreclr/jit/compiler.hpp
@@ -101,6 +101,11 @@ inline bool genExactlyOneBit(T value)
inline regMaskTP genFindLowestBit(regMaskTP value)
{
+#ifdef HAS_MORE_THAN_64_REGISTERS
+ // If we ever need to use this method for predicate
+ // registers, then handle it.
+ assert(value.getHigh() == RBM_NONE);
+#endif
return regMaskTP(genFindLowestBit(value.getLow()));
}
@@ -111,19 +116,14 @@ inline regMaskTP genFindLowestBit(regMaskTP value)
inline bool genMaxOneBit(regMaskTP value)
{
+#ifdef HAS_MORE_THAN_64_REGISTERS
+ // If we ever need to use this method for predicate
+ // registers, then handle it.
+ assert(value.getHigh() == RBM_NONE);
+#endif
return genMaxOneBit(value.getLow());
}
-/*****************************************************************************
- *
- * Return true if the given value has exactly one bit set.
- */
-
-inline bool genExactlyOneBit(regMaskTP value)
-{
- return genExactlyOneBit(value.getLow());
-}
-
/*****************************************************************************
*
* Given a value that has exactly one bit set, return the position of that
@@ -169,7 +169,7 @@ inline unsigned uhi32(uint64_t value)
inline unsigned genCountBits(regMaskTP mask)
{
- return BitOperations::PopCount(mask.getLow());
+ return PopCount(mask);
}
/*****************************************************************************
@@ -933,8 +933,40 @@ inline unsigned Compiler::funGetFuncIdx(BasicBlock* block)
// Assumptions:
// The mask contains one and only one register.
-inline regNumber genRegNumFromMask(regMaskTP mask)
+inline regNumber genRegNumFromMask(const SingleTypeRegSet& mask)
+{
+ assert(mask != RBM_NONE); // Must have one bit set, so can't have a mask of zero
+
+ /* Convert the mask to a register number */
+
+ regNumber regNum = (regNumber)genLog2(mask);
+
+ /* Make sure we got it right */
+ assert(genSingleTypeRegMask(regNum) == mask);
+
+ return regNum;
+}
+
+//------------------------------------------------------------------------------
+// genRegNumFromMask : Maps a single register mask having gpr/float to a register number.
+// If the mask can contain predicate register, use genRegNumFromMask(reg, type)
+//
+// Arguments:
+// mask - the register mask
+//
+// Return Value:
+// The number of the register contained in the mask.
+//
+// Assumptions:
+// The mask contains one and only one register.
+
+inline regNumber genRegNumFromMask(const regMaskTP& mask)
{
+#ifdef HAS_MORE_THAN_64_REGISTERS
+ // This method is only used for gpr/float
+ assert(mask.getHigh() == RBM_NONE);
+#endif
+
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero
/* Convert the mask to a register number */
@@ -942,7 +974,74 @@ inline regNumber genRegNumFromMask(regMaskTP mask)
regNumber regNum = (regNumber)genLog2(mask.getLow());
/* Make sure we got it right */
- assert(genRegMask(regNum) == mask.getLow());
+ assert(genRegMask(regNum).getLow() == mask.getLow());
+
+ return regNum;
+}
+
+//------------------------------------------------------------------------------
+// genRegNumFromMask : Maps a single register mask to a register number.
+//
+// Arguments:
+// mask - the register mask
+// type - The
+//
+// Return Value:
+// The number of the register contained in the mask.
+//
+// Assumptions:
+// The mask contains one and only one register.
+
+inline regNumber genRegNumFromMask(SingleTypeRegSet mask, var_types type)
+{
+ regNumber regNum = genRegNumFromMask(mask);
+
+#ifdef HAS_MORE_THAN_64_REGISTERS
+ if (varTypeIsMask(type))
+ {
+ regNum = (regNumber)(64 + regNum);
+ }
+#endif
+ return regNum;
+}
+
+//------------------------------------------------------------------------------
+// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
+//
+// Arguments:
+// mask - the register mask
+//
+// Return Value:
+// The number of the first register contained in the mask.
+//
+// TODO: check if const regMaskTP& matter or should we pass by value
+inline regNumber genFirstRegNumFromMask(const regMaskTP& mask)
+{
+ assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero
+
+ /* Convert the mask to a register number */
+
+ regNumber regNum = (regNumber)BitScanForward(mask);
+
+ return regNum;
+}
+
+//------------------------------------------------------------------------------
+// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
+//
+// Arguments:
+// mask - the register mask
+//
+// Return Value:
+// The number of the first register contained in the mask.
+//
+inline regNumber genFirstRegNumFromMask(SingleTypeRegSet mask)
+{
+ assert(mask != RBM_NONE); // Must have one bit set, so can't have a mask of zero
+
+ /* Convert the mask to a register number */
+
+ regNumber regNum = (regNumber)BitOperations::BitScanForward(mask);
return regNum;
}
@@ -966,28 +1065,31 @@ inline regNumber genFirstRegNumFromMaskAndToggle(regMaskTP& mask)
regNumber regNum = (regNumber)BitScanForward(mask);
- mask ^= genRegMask(regNum);
+ mask.RemoveRegNumFromMask(regNum);
return regNum;
}
//------------------------------------------------------------------------------
-// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
-//
+// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
+// register number and also toggle the bit in the `mask`.
// Arguments:
// mask - the register mask
//
// Return Value:
-// The number of the first register contained in the mask.
+// The number of the first register contained in the mask and updates the `mask` to toggle
+// the bit.
//
-inline regNumber genFirstRegNumFromMask(regMaskTP mask)
+inline regNumber genFirstRegNumFromMaskAndToggle(SingleTypeRegSet& mask)
{
- assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero
+ assert(mask != RBM_NONE); // Must have one bit set, so can't have a mask of zero
/* Convert the mask to a register number */
- regNumber regNum = (regNumber)BitScanForward(mask);
+ regNumber regNum = (regNumber)BitOperations::BitScanForward(mask);
+
+ mask ^= genSingleTypeRegMask(regNum);
return regNum;
}
@@ -3190,6 +3292,41 @@ inline bool Compiler::IsValidLclAddr(unsigned lclNum, unsigned offset)
return (offset < UINT16_MAX) && (offset < lvaLclExactSize(lclNum));
}
+//------------------------------------------------------------------------
+// IsPotentialGCSafePoint: Can the given tree be effectively a gc safe point?
+//
+// Arguments:
+// tree - the tree to check
+//
+// Return Value:
+// True if the tree can be a gc safe point
+//
+inline bool Compiler::IsPotentialGCSafePoint(GenTree* tree) const
+{
+ if (((tree->gtFlags & GTF_CALL) != 0))
+ {
+ // if this is not a No-GC helper
+ if (!tree->IsCall() || !emitter::emitNoGChelper(tree->AsCall()->GetHelperNum()))
+ {
+ // assume that we have a safe point.
+ return true;
+ }
+ }
+
+ // TYP_STRUCT-typed stores might be converted into calls (with gc safe points) in Lower.
+ // This is quite a conservative fix as it's hard to prove Lower won't do it at this point.
+ if (tree->OperIsLocalStore())
+ {
+ return tree->TypeIs(TYP_STRUCT);
+ }
+ if (tree->OperIs(GT_STORE_BLK))
+ {
+ return true;
+ }
+
+ return false;
+}
+
/*
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
diff --git a/src/coreclr/jit/emitarm64sve.cpp b/src/coreclr/jit/emitarm64sve.cpp
index 80f1d55e97fd2..1fee8e529b170 100644
--- a/src/coreclr/jit/emitarm64sve.cpp
+++ b/src/coreclr/jit/emitarm64sve.cpp
@@ -2057,6 +2057,7 @@ void emitter::emitInsSve_R_R(instruction ins,
break;
case INS_sve_cntp:
+ assert(isScalableVectorSize(size));
assert(insOptsScalableStandard(opt));
assert(insScalableOptsWithVectorLength(sopt)); // l
assert(isGeneralRegister(reg1)); // ddddd
@@ -3918,7 +3919,7 @@ void emitter::emitInsSve_R_R_R(instruction ins,
break;
case INS_sve_cntp:
- assert(size == EA_8BYTE);
+ assert(isScalableVectorSize(size));
assert(isGeneralRegister(reg1)); // ddddd
assert(isPredicateRegister(reg2)); // gggg
assert(isPredicateRegister(reg3)); // NNNN
@@ -4383,6 +4384,12 @@ void emitter::emitInsSve_R_R_R(instruction ins,
case INS_sve_ld1w:
case INS_sve_ld1sw:
case INS_sve_ld1d:
+ case INS_sve_ldnf1b:
+ case INS_sve_ldnf1sb:
+ case INS_sve_ldnf1h:
+ case INS_sve_ldnf1sh:
+ case INS_sve_ldnf1w:
+ case INS_sve_ldnf1sw:
return emitIns_R_R_R_I(ins, size, reg1, reg2, reg3, 0, opt);
default:
@@ -13077,7 +13084,7 @@ void emitter::emitInsSveSanityCheck(instrDesc* id)
break;
case IF_SVE_DK_3A: // ........xx...... ..gggg.NNNNddddd -- SVE predicate count
- assert(id->idOpSize() == EA_8BYTE);
+ assert(isScalableVectorSize(id->idOpSize()));
assert(insOptsScalableStandard(id->idInsOpt()));
assert(isGeneralRegister(id->idReg1())); // ddddd
assert(isPredicateRegister(id->idReg2())); // gggg
@@ -13338,9 +13345,13 @@ void emitter::emitInsSveSanityCheck(instrDesc* id)
break;
case IF_SVE_DL_2A: // ........xx...... .....l.NNNNddddd -- SVE predicate count (predicate-as-counter)
- assert(id->idOpSize() == EA_8BYTE);
+ assert(insOptsScalableStandard(id->idInsOpt()));
+ assert(isValidVectorElemsize(optGetSveElemsize(id->idInsOpt()))); // xx
+ assert(isGeneralRegister(id->idReg1())); // ddddd
+ assert(isPredicateRegister(id->idReg2())); // NNNN
+ assert(isScalableVectorSize(id->idOpSize()));
+ break;
- FALLTHROUGH;
case IF_SVE_DO_2A: // ........xx...... .....X.MMMMddddd -- SVE saturating inc/dec register by predicate count
case IF_SVE_DM_2A: // ........xx...... .......MMMMddddd -- SVE inc/dec register by predicate count
assert(insOptsScalableStandard(id->idInsOpt()));
@@ -15216,8 +15227,8 @@ void emitter::emitDispInsSveHelp(instrDesc* id)
break;
// , , .
- case IF_SVE_DK_3A: // ........xx...... ..gggg.NNNNddddd -- SVE predicate count
- emitDispReg(id->idReg1(), size, true); // ddddd
+ case IF_SVE_DK_3A: // ........xx...... ..gggg.NNNNddddd -- SVE predicate count
+ emitDispReg(id->idReg1(), EA_8BYTE, true); // ddddd
emitDispPredicateReg(id->idReg2(), insGetPredicateType(fmt, 2), id->idInsOpt(), true); // gggg
emitDispPredicateReg(id->idReg3(), insGetPredicateType(fmt, 3), id->idInsOpt(), false); // NNNN
break;
@@ -15238,7 +15249,7 @@ void emitter::emitDispInsSveHelp(instrDesc* id)
// , .,
case IF_SVE_DL_2A: // ........xx...... .....l.NNNNddddd -- SVE predicate count (predicate-as-counter)
- emitDispReg(id->idReg1(), id->idOpSize(), true); // ddddd
+ emitDispReg(id->idReg1(), EA_8BYTE, true); // ddddd
emitDispPredicateReg(id->idReg2(), insGetPredicateType(fmt), id->idInsOpt(), true); // NNNN
emitDispVectorLengthSpecifier(id);
break;
diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp
index f1451dc83ef2c..e72777a296e61 100644
--- a/src/coreclr/jit/emitriscv64.cpp
+++ b/src/coreclr/jit/emitriscv64.cpp
@@ -3347,15 +3347,29 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
return sz;
}
-bool emitter::emitDispBranchInstrType(unsigned opcode2) const
+/*****************************************************************************/
+/*****************************************************************************/
+
+// clang-format off
+static const char* const RegNames[] =
{
+ #define REGDEF(name, rnum, mask, sname) sname,
+ #include "register.h"
+};
+// clang-format on
+
+bool emitter::emitDispBranchInstrType(unsigned opcode2, bool is_zero_reg, bool& print_second_reg) const
+{
+ print_second_reg = true;
switch (opcode2)
{
case 0:
- printf("beq ");
+ printf(is_zero_reg ? "beqz" : "beq ");
+ print_second_reg = !is_zero_reg;
break;
case 1:
- printf("bne ");
+ printf(is_zero_reg ? "bnez" : "bne ");
+ print_second_reg = !is_zero_reg;
break;
case 4:
printf("blt ");
@@ -3407,17 +3421,19 @@ void emitter::emitDispBranchLabel(const instrDesc* id) const
printf("L_M%03u_", FMT_BB, emitComp->compMethodID, id->idAddr()->iiaBBlabel->bbNum);
}
-bool emitter::emitDispBranch(unsigned opcode2,
- const char* register1Name,
- const char* register2Name,
- const instrDesc* id,
- const insGroup* ig) const
+bool emitter::emitDispBranch(
+ unsigned opcode2, unsigned rs1, unsigned rs2, const instrDesc* id, const insGroup* ig) const
{
- if (!emitDispBranchInstrType(opcode2))
+ bool print_second_reg = true;
+ if (!emitDispBranchInstrType(opcode2, rs2 == REG_ZERO, print_second_reg))
{
return false;
}
- printf(" %s, %s, ", register1Name, register2Name);
+ printf(" %s, ", RegNames[rs1]);
+ if (print_second_reg)
+ {
+ printf("%s, ", RegNames[rs2]);
+ }
assert(id != nullptr);
if (id->idAddr()->iiaHasInstrCount())
{
@@ -3438,17 +3454,6 @@ void emitter::emitDispIllegalInstruction(code_t instructionCode)
printf("RISCV64 illegal instruction: 0x%08X\n", instructionCode);
}
-/*****************************************************************************/
-/*****************************************************************************/
-
-// clang-format off
-static const char* const RegNames[] =
-{
- #define REGDEF(name, rnum, mask, sname) sname,
- #include "register.h"
-};
-// clang-format on
-
//----------------------------------------------------------------------------------------
// Disassemble the given instruction.
// The `emitter::emitDispInsName` is focused on the most important for debugging.
@@ -3470,6 +3475,8 @@ static const char* const RegNames[] =
void emitter::emitDispInsName(
code_t code, const BYTE* addr, bool doffs, unsigned insOffset, const instrDesc* id, const insGroup* ig)
{
+ static constexpr int kMaxInstructionLength = 14;
+
const BYTE* insAdr = addr - writeableOffset;
unsigned int opcode = code & 0x7f;
@@ -3506,51 +3513,95 @@ void emitter::emitDispInsName(
}
case 0x13:
{
- unsigned int opcode2 = (code >> 12) & 0x7;
- const char* rd = RegNames[(code >> 7) & 0x1f];
- const char* rs1 = RegNames[(code >> 15) & 0x1f];
- int imm12 = (((int)code) >> 20); // & 0xfff;
- // if (imm12 & 0x800)
- //{
- // imm12 |= 0xfffff000;
- //}
+ unsigned opcode2 = (code >> 12) & 0x7;
+ unsigned rd = (code >> 7) & 0x1f;
+ unsigned rs1 = (code >> 15) & 0x1f;
+ int imm12 = static_cast(code) >> 20;
+ bool isHex = false;
+ bool hasImmediate = true;
+ int printLength = 0;
+
switch (opcode2)
{
- case 0x0: // ADDI
- printf("addi %s, %s, %d\n", rd, rs1, imm12);
- return;
- case 0x1: // SLLI
- printf("slli %s, %s, %d\n", rd, rs1, imm12 & 0x3f); // 6 BITS for SHAMT in RISCV64
- return;
+ case 0x0: // ADDI & MV & NOP
+ if (code == emitInsCode(INS_nop))
+ {
+ printf("nop\n");
+ return;
+ }
+ else if (imm12 != 0)
+ {
+ printLength = printf("addi");
+ }
+ else
+ {
+ printLength = printf("mv");
+ hasImmediate = false;
+ }
+ break;
+ case 0x1: // SLLI
+ {
+ static constexpr unsigned kSlliFunct6 = 0b000000;
+
+ unsigned funct6 = (imm12 >> 6) & 0x3f;
+ // SLLI's instruction code's upper 6 bits have to be equal to zero
+ if (funct6 != kSlliFunct6)
+ {
+ return emitDispIllegalInstruction(code);
+ }
+ printLength = printf("slli");
+ imm12 &= 0x3f; // 6 BITS for SHAMT in RISCV64
+ }
+ break;
case 0x2: // SLTI
- printf("slti %s, %s, %d\n", rd, rs1, imm12);
- return;
+ printLength = printf("slti");
+ break;
case 0x3: // SLTIU
- printf("sltiu %s, %s, %d\n", rd, rs1, imm12);
- return;
+ printLength = printf("sltiu");
+ break;
case 0x4: // XORI
- printf("xori %s, %s, 0x%x\n", rd, rs1, imm12);
- return;
+ printLength = printf("xori");
+ isHex = true;
+ break;
case 0x5: // SRLI & SRAI
- if (((code >> 30) & 0x1) == 0)
- {
- printf("srli %s, %s, %d\n", rd, rs1, imm12 & 0x3f); // 6BITS for SHAMT in RISCV64
- }
- else
+ {
+ static constexpr unsigned kLogicalShiftFunct6 = 0b000000;
+ static constexpr unsigned kArithmeticShiftFunct6 = 0b010000;
+
+ unsigned funct6 = (imm12 >> 6) & 0x3f;
+ bool isLogicalShift = funct6 == kLogicalShiftFunct6;
+ if ((!isLogicalShift) && (funct6 != kArithmeticShiftFunct6))
{
- printf("srai %s, %s, %d\n", rd, rs1, imm12 & 0x3f); // 6BITS for SHAMT in RISCV64
+ return emitDispIllegalInstruction(code);
}
- return;
+ printLength = printf(isLogicalShift ? "srli" : "srai");
+ imm12 &= 0x3f; // 6BITS for SHAMT in RISCV64
+ }
+ break;
case 0x6: // ORI
- printf("ori %s, %s, 0x%x\n", rd, rs1, imm12 & 0xfff);
- return;
+ printLength = printf("ori");
+ imm12 &= 0xfff;
+ isHex = true;
+ break;
case 0x7: // ANDI
- printf("andi %s, %s, 0x%x\n", rd, rs1, imm12 & 0xfff);
- return;
+ printLength = printf("andi");
+ imm12 &= 0xfff;
+ isHex = true;
+ break;
default:
- printf("RISCV64 illegal instruction: 0x%08X\n", code);
- return;
+ return emitDispIllegalInstruction(code);
}
+ assert(printLength > 0);
+ int paddingLength = kMaxInstructionLength - printLength;
+
+ printf("%*s %s, %s", paddingLength, "", RegNames[rd], RegNames[rs1]);
+ if (hasImmediate)
+ {
+ printf(isHex ? ", 0x%x" : ", %d", imm12);
+ }
+ printf("\n");
+
+ return;
}
case 0x1b:
{
@@ -3574,185 +3625,198 @@ void emitter::emitDispInsName(
printf("addiw %s, %s, %d\n", rd, rs1, imm12);
}
return;
- case 0x1: // SLLIW
- printf("slliw %s, %s, %d\n", rd, rs1, imm12 & 0x3f); // 6 BITS for SHAMT in RISCV64
+ case 0x1: // SLLIW
+ {
+ static constexpr unsigned kSlliwFunct7 = 0b0000000;
+
+ unsigned funct7 = (imm12 >> 5) & 0x7f;
+ // SLLIW's instruction code's upper 7 bits have to be equal to zero
+ if (funct7 == kSlliwFunct7)
+ {
+ printf("slliw %s, %s, %d\n", rd, rs1, imm12 & 0x1f); // 5 BITS for SHAMT in RISCV64
+ }
+ else
+ {
+ emitDispIllegalInstruction(code);
+ }
+ }
return;
case 0x5: // SRLIW & SRAIW
- if (((code >> 30) & 0x1) == 0)
+ {
+ static constexpr unsigned kLogicalShiftFunct7 = 0b0000000;
+ static constexpr unsigned kArithmeticShiftFunct7 = 0b0100000;
+
+ unsigned funct7 = (imm12 >> 5) & 0x7f;
+ if (funct7 == kLogicalShiftFunct7)
{
printf("srliw %s, %s, %d\n", rd, rs1, imm12 & 0x1f); // 5BITS for SHAMT in RISCV64
}
- else
+ else if (funct7 == kArithmeticShiftFunct7)
{
printf("sraiw %s, %s, %d\n", rd, rs1, imm12 & 0x1f); // 5BITS for SHAMT in RISCV64
}
+ else
+ {
+ emitDispIllegalInstruction(code);
+ }
+ }
return;
default:
- printf("RISCV64 illegal instruction: 0x%08X\n", code);
- return;
+ return emitDispIllegalInstruction(code);
}
}
case 0x33:
{
- unsigned int opcode2 = (code >> 25) & 0x3;
+ unsigned int opcode2 = (code >> 25) & 0x7f;
unsigned int opcode3 = (code >> 12) & 0x7;
const char* rd = RegNames[(code >> 7) & 0x1f];
const char* rs1 = RegNames[(code >> 15) & 0x1f];
const char* rs2 = RegNames[(code >> 20) & 0x1f];
- if (opcode2 == 0)
+
+ switch (opcode2)
{
- switch (opcode3)
- {
- case 0x0: // ADD & SUB
- if (((code >> 30) & 0x1) == 0)
- {
+ case 0b0000000:
+ switch (opcode3)
+ {
+ case 0x0: // ADD
printf("add %s, %s, %s\n", rd, rs1, rs2);
- }
- else
- {
- printf("sub %s, %s, %s\n", rd, rs1, rs2);
- }
- return;
- case 0x1: // SLL
- printf("sll %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x2: // SLT
- printf("slt %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x3: // SLTU
- printf("sltu %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x4: // XOR
- printf("xor %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x5: // SRL & SRA
- if (((code >> 30) & 0x1) == 0)
- {
+ return;
+ case 0x1: // SLL
+ printf("sll %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x2: // SLT
+ printf("slt %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x3: // SLTU
+ printf("sltu %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x4: // XOR
+ printf("xor %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x5: // SRL
printf("srl %s, %s, %s\n", rd, rs1, rs2);
- }
- else
- {
+ return;
+ case 0x6: // OR
+ printf("or %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x7: // AND
+ printf("and %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ default:
+ return emitDispIllegalInstruction(code);
+ }
+ return;
+ case 0b0100000:
+ switch (opcode3)
+ {
+ case 0x0: // SUB
+ printf("sub %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x5: // SRA
printf("sra %s, %s, %s\n", rd, rs1, rs2);
- }
- return;
- case 0x6: // OR
- printf("or %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x7: // AND
- printf("and %s, %s, %s\n", rd, rs1, rs2);
- return;
- default:
- printf("RISCV64 illegal instruction: 0x%08X\n", code);
- return;
- }
- }
- else if (opcode2 == 0x1)
- {
- switch (opcode3)
- {
- case 0x0: // MUL
- printf("mul %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x1: // MULH
- printf("mulh %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x2: // MULHSU
- printf("mulhsu %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x3: // MULHU
- printf("mulhu %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x4: // DIV
- printf("div %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x5: // DIVU
- printf("divu %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x6: // REM
- printf("rem %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x7: // REMU
- printf("remu %s, %s, %s\n", rd, rs1, rs2);
- return;
- default:
- printf("RISCV64 illegal instruction: 0x%08X\n", code);
- return;
- }
- }
- else
- {
- printf("RISCV64 illegal instruction: 0x%08X\n", code);
- return;
+ return;
+ default:
+ return emitDispIllegalInstruction(code);
+ }
+ return;
+ case 0b0000001:
+ switch (opcode3)
+ {
+ case 0x0: // MUL
+ printf("mul %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x1: // MULH
+ printf("mulh %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x2: // MULHSU
+ printf("mulhsu %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x3: // MULHU
+ printf("mulhu %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x4: // DIV
+ printf("div %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x5: // DIVU
+ printf("divu %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x6: // REM
+ printf("rem %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x7: // REMU
+ printf("remu %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ default:
+ return emitDispIllegalInstruction(code);
+ }
+ return;
+ default:
+ return emitDispIllegalInstruction(code);
}
}
case 0x3b:
{
- unsigned int opcode2 = (code >> 25) & 0x3;
+ unsigned int opcode2 = (code >> 25) & 0x7f;
unsigned int opcode3 = (code >> 12) & 0x7;
const char* rd = RegNames[(code >> 7) & 0x1f];
const char* rs1 = RegNames[(code >> 15) & 0x1f];
const char* rs2 = RegNames[(code >> 20) & 0x1f];
- if (opcode2 == 0)
+ switch (opcode2)
{
- switch (opcode3)
- {
- case 0x0: // ADDW & SUBW
- if (((code >> 30) & 0x1) == 0)
- {
+ case 0b0000000:
+ switch (opcode3)
+ {
+ case 0x0: // ADDW
printf("addw %s, %s, %s\n", rd, rs1, rs2);
- }
- else
- {
- printf("subw %s, %s, %s\n", rd, rs1, rs2);
- }
- return;
- case 0x1: // SLLW
- printf("sllw %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x5: // SRLW & SRAW
- if (((code >> 30) & 0x1) == 0)
- {
+ return;
+ case 0x1: // SLLW
+ printf("sllw %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x5: // SRLW
printf("srlw %s, %s, %s\n", rd, rs1, rs2);
- }
- else
- {
+ return;
+ default:
+ return emitDispIllegalInstruction(code);
+ }
+ return;
+ case 0b0100000:
+ switch (opcode3)
+ {
+ case 0x0: // SUBW
+ printf("subw %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x5: // SRAW
printf("sraw %s, %s, %s\n", rd, rs1, rs2);
- }
- return;
- default:
- printf("RISCV64 illegal instruction: 0x%08X\n", code);
- return;
- }
- }
- else if (opcode2 == 1)
- {
- switch (opcode3)
- {
- case 0x0: // MULW
- printf("mulw %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x4: // DIVW
- printf("divw %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x5: // DIVUW
- printf("divuw %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x6: // REMW
- printf("remw %s, %s, %s\n", rd, rs1, rs2);
- return;
- case 0x7: // REMUW
- printf("remuw %s, %s, %s\n", rd, rs1, rs2);
- return;
- default:
- printf("RISCV64 illegal instruction: 0x%08X\n", code);
- return;
- }
- }
- else
- {
- printf("RISCV64 illegal instruction: 0x%08X\n", code);
- return;
+ return;
+ default:
+ return emitDispIllegalInstruction(code);
+ }
+ return;
+ case 0b0000001:
+ switch (opcode3)
+ {
+ case 0x0: // MULW
+ printf("mulw %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x4: // DIVW
+ printf("divw %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x5: // DIVUW
+ printf("divuw %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x6: // REMW
+ printf("remw %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ case 0x7: // REMUW
+ printf("remuw %s, %s, %s\n", rd, rs1, rs2);
+ return;
+ default:
+ return emitDispIllegalInstruction(code);
+ }
+ return;
+ default:
+ return emitDispIllegalInstruction(code);
}
}
case 0x23:
@@ -3787,9 +3851,9 @@ void emitter::emitDispInsName(
}
case 0x63: // BRANCH
{
- unsigned int opcode2 = (code >> 12) & 0x7;
- const char* rs1 = RegNames[(code >> 15) & 0x1f];
- const char* rs2 = RegNames[(code >> 20) & 0x1f];
+ unsigned opcode2 = (code >> 12) & 0x7;
+ unsigned rs1 = (code >> 15) & 0x1f;
+ unsigned rs2 = (code >> 20) & 0x1f;
// int offset = (((code >> 31) & 0x1) << 12) | (((code >> 7) & 0x1) << 11) | (((code >> 25) & 0x3f) << 5) |
// (((code >> 8) & 0xf) << 1);
// if (offset & 0x800)
@@ -3866,14 +3930,21 @@ void emitter::emitDispInsName(
}
case 0x6f:
{
- const char* rd = RegNames[(code >> 7) & 0x1f];
- int offset = (((code >> 31) & 0x1) << 20) | (((code >> 12) & 0xff) << 12) | (((code >> 20) & 0x1) << 11) |
+ unsigned rd = (code >> 7) & 0x1f;
+ int offset = (((code >> 31) & 0x1) << 20) | (((code >> 12) & 0xff) << 12) | (((code >> 20) & 0x1) << 11) |
(((code >> 21) & 0x3ff) << 1);
if (offset & 0x80000)
{
offset |= 0xfff00000;
}
- printf("jal %s, %d", rd, offset);
+ if (rd == REG_ZERO)
+ {
+ printf("j %d", offset);
+ }
+ else
+ {
+ printf("jal %s, %d", RegNames[rd], offset);
+ }
CORINFO_METHOD_HANDLE handle = (CORINFO_METHOD_HANDLE)id->idDebugOnlyInfo()->idMemCookie;
if (handle != 0)
{
diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h
index 5409c76233de9..6c73f3fe577fc 100644
--- a/src/coreclr/jit/emitriscv64.h
+++ b/src/coreclr/jit/emitriscv64.h
@@ -63,14 +63,10 @@ bool emitInsIsLoadOrStore(instruction ins);
void emitDispInsName(
code_t code, const BYTE* addr, bool doffs, unsigned insOffset, const instrDesc* id, const insGroup* ig);
void emitDispInsInstrNum(const instrDesc* id) const;
-bool emitDispBranch(unsigned opcode2,
- const char* register1Name,
- const char* register2Name,
- const instrDesc* id,
- const insGroup* ig) const;
+bool emitDispBranch(unsigned opcode2, unsigned rs1, unsigned rs2, const instrDesc* id, const insGroup* ig) const;
void emitDispBranchOffset(const instrDesc* id, const insGroup* ig) const;
void emitDispBranchLabel(const instrDesc* id) const;
-bool emitDispBranchInstrType(unsigned opcode2) const;
+bool emitDispBranchInstrType(unsigned opcode2, bool is_zero_reg, bool& print_second_reg) const;
void emitDispIllegalInstruction(code_t instructionCode);
emitter::code_t emitInsCode(instruction ins /*, insFormat fmt*/) const;
diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp
index 9895d5c940c04..56d8a1bca6c1f 100644
--- a/src/coreclr/jit/fgbasic.cpp
+++ b/src/coreclr/jit/fgbasic.cpp
@@ -1400,10 +1400,6 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
case NI_Vector3_Create:
case NI_Vector3_CreateBroadcast:
case NI_Vector3_CreateFromVector2:
- case NI_Vector4_Create:
- case NI_Vector4_CreateBroadcast:
- case NI_Vector4_CreateFromVector2:
- case NI_Vector4_CreateFromVector3:
case NI_Vector128_Create:
case NI_Vector128_CreateScalar:
case NI_Vector128_CreateScalarUnsafe:
@@ -1630,82 +1626,6 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
break;
}
-#if defined(FEATURE_HW_INTRINSICS)
-#if defined(TARGET_ARM64)
- case NI_Vector64_As:
- case NI_Vector64_AsByte:
- case NI_Vector64_AsDouble:
- case NI_Vector64_AsInt16:
- case NI_Vector64_AsInt32:
- case NI_Vector64_AsInt64:
- case NI_Vector64_AsNInt:
- case NI_Vector64_AsNUInt:
- case NI_Vector64_AsSByte:
- case NI_Vector64_AsSingle:
- case NI_Vector64_AsUInt16:
- case NI_Vector64_AsUInt32:
- case NI_Vector64_AsUInt64:
- case NI_Vector64_op_UnaryPlus:
-#endif // TARGET_XARCH
- case NI_Vector128_As:
- case NI_Vector128_AsByte:
- case NI_Vector128_AsDouble:
- case NI_Vector128_AsInt16:
- case NI_Vector128_AsInt32:
- case NI_Vector128_AsInt64:
- case NI_Vector128_AsNInt:
- case NI_Vector128_AsNUInt:
- case NI_Vector128_AsSByte:
- case NI_Vector128_AsSingle:
- case NI_Vector128_AsUInt16:
- case NI_Vector128_AsUInt32:
- case NI_Vector128_AsUInt64:
- case NI_Vector128_AsVector4:
- case NI_Vector128_op_UnaryPlus:
- case NI_VectorT_As:
- case NI_VectorT_AsVectorByte:
- case NI_VectorT_AsVectorDouble:
- case NI_VectorT_AsVectorInt16:
- case NI_VectorT_AsVectorInt32:
- case NI_VectorT_AsVectorInt64:
- case NI_VectorT_AsVectorNInt:
- case NI_VectorT_AsVectorNUInt:
- case NI_VectorT_AsVectorSByte:
- case NI_VectorT_AsVectorSingle:
- case NI_VectorT_AsVectorUInt16:
- case NI_VectorT_AsVectorUInt32:
- case NI_VectorT_AsVectorUInt64:
- case NI_VectorT_op_UnaryPlus:
-#if defined(TARGET_XARCH)
- case NI_Vector256_As:
- case NI_Vector256_AsByte:
- case NI_Vector256_AsDouble:
- case NI_Vector256_AsInt16:
- case NI_Vector256_AsInt32:
- case NI_Vector256_AsInt64:
- case NI_Vector256_AsNInt:
- case NI_Vector256_AsNUInt:
- case NI_Vector256_AsSByte:
- case NI_Vector256_AsSingle:
- case NI_Vector256_AsUInt16:
- case NI_Vector256_AsUInt32:
- case NI_Vector256_AsUInt64:
- case NI_Vector256_op_UnaryPlus:
- case NI_Vector512_As:
- case NI_Vector512_AsByte:
- case NI_Vector512_AsDouble:
- case NI_Vector512_AsInt16:
- case NI_Vector512_AsInt32:
- case NI_Vector512_AsInt64:
- case NI_Vector512_AsNInt:
- case NI_Vector512_AsNUInt:
- case NI_Vector512_AsSByte:
- case NI_Vector512_AsSingle:
- case NI_Vector512_AsUInt16:
- case NI_Vector512_AsUInt32:
- case NI_Vector512_AsUInt64:
-#endif // TARGET_XARCH
-#endif // FEATURE_HW_INTRINSICS
case NI_SRCS_UNSAFE_As:
case NI_SRCS_UNSAFE_AsRef:
case NI_SRCS_UNSAFE_BitCast:
@@ -1724,27 +1644,16 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
#if defined(TARGET_ARM64)
case NI_Vector64_get_AllBitsSet:
case NI_Vector64_get_One:
- case NI_Vector64_get_Zero:
#endif // TARGET_ARM64
- case NI_Vector2_get_One:
- case NI_Vector2_get_Zero:
- case NI_Vector3_get_One:
- case NI_Vector3_get_Zero:
- case NI_Vector4_get_One:
- case NI_Vector4_get_Zero:
case NI_Vector128_get_AllBitsSet:
case NI_Vector128_get_One:
- case NI_Vector128_get_Zero:
case NI_VectorT_get_AllBitsSet:
case NI_VectorT_get_One:
- case NI_VectorT_get_Zero:
#if defined(TARGET_XARCH)
case NI_Vector256_get_AllBitsSet:
case NI_Vector256_get_One:
- case NI_Vector256_get_Zero:
case NI_Vector512_get_AllBitsSet:
case NI_Vector512_get_One:
- case NI_Vector512_get_Zero:
#endif // TARGET_XARCH
#endif // FEATURE_HW_INTRINSICS
{
diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp
index 47a8c243a2e9e..d05a815b12f71 100644
--- a/src/coreclr/jit/flowgraph.cpp
+++ b/src/coreclr/jit/flowgraph.cpp
@@ -4141,6 +4141,28 @@ FlowGraphNaturalLoop::FlowGraphNaturalLoop(const FlowGraphDfsTree* dfsTree, Basi
{
}
+//------------------------------------------------------------------------
+// GetPreheader: Get the preheader of this loop, if it has one.
+//
+// Returns:
+// The preheader, or nullptr if there is no preheader.
+//
+BasicBlock* FlowGraphNaturalLoop::GetPreheader() const
+{
+ if (m_entryEdges.size() != 1)
+ {
+ return nullptr;
+ }
+
+ BasicBlock* preheader = m_entryEdges[0]->getSourceBlock();
+ if (!preheader->KindIs(BBJ_ALWAYS))
+ {
+ return nullptr;
+ }
+
+ return preheader;
+}
+
//------------------------------------------------------------------------
// GetDepth: Get the depth of the loop.
//
diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp
index 78a6aef4267e1..949d611519e4c 100644
--- a/src/coreclr/jit/gentree.cpp
+++ b/src/coreclr/jit/gentree.cpp
@@ -4128,6 +4128,8 @@ unsigned Compiler::gtSetMultiOpOrder(GenTreeMultiOp* multiOp)
// first tree to be evaluated, and "lvl2" - the second.
if (multiOp->IsReverseOp())
{
+ assert(!multiOp->AsHWIntrinsic()->IsUserCall());
+
level = gtSetEvalOrder(multiOp->Op(2));
lvl2 = gtSetEvalOrder(multiOp->Op(1));
}
@@ -4140,11 +4142,18 @@ unsigned Compiler::gtSetMultiOpOrder(GenTreeMultiOp* multiOp)
// We want the more complex tree to be evaluated first.
if (level < lvl2)
{
- bool canSwap = multiOp->IsReverseOp() ? gtCanSwapOrder(multiOp->Op(2), multiOp->Op(1))
- : gtCanSwapOrder(multiOp->Op(1), multiOp->Op(2));
+ bool canSwap = false;
+
+ if (!multiOp->AsHWIntrinsic()->IsUserCall())
+ {
+ canSwap = multiOp->IsReverseOp() ? gtCanSwapOrder(multiOp->Op(2), multiOp->Op(1))
+ : gtCanSwapOrder(multiOp->Op(1), multiOp->Op(2));
+ }
if (canSwap)
{
+ assert(!multiOp->AsHWIntrinsic()->IsUserCall());
+
if (multiOp->IsReverseOp())
{
multiOp->ClearReverseOp();
@@ -6563,7 +6572,7 @@ bool GenTree::OperSupportsReverseOpEvalOrder(Compiler* comp) const
#if defined(FEATURE_SIMD) || defined(FEATURE_HW_INTRINSICS)
if (OperIsMultiOp())
{
- return AsMultiOp()->GetOperandCount() == 2;
+ return (AsMultiOp()->GetOperandCount() == 2) && !AsMultiOp()->IsUserCall();
}
#endif // FEATURE_SIMD || FEATURE_HW_INTRINSICS
return false;
@@ -7227,8 +7236,6 @@ ExceptionSetFlags GenTree::OperExceptions(Compiler* comp)
if (hwIntrinsicNode->OperIsMemoryLoadOrStore())
{
- assert((gtFlags & GTF_IND_NONFAULTING) == 0);
-
// TODO-CQ: We should use comp->fgAddrCouldBeNull on the address operand
// to determine if this can actually produce an NRE or not
@@ -9626,10 +9633,8 @@ GenTree* Compiler::gtCloneExpr(GenTree* tree)
case GT_INTRINSIC:
copy = new (this, GT_INTRINSIC)
GenTreeIntrinsic(tree->TypeGet(), tree->AsOp()->gtOp1, tree->AsOp()->gtOp2,
- tree->AsIntrinsic()->gtIntrinsicName, tree->AsIntrinsic()->gtMethodHandle);
-#ifdef FEATURE_READYTORUN
- copy->AsIntrinsic()->gtEntryPoint = tree->AsIntrinsic()->gtEntryPoint;
-#endif
+ tree->AsIntrinsic()->gtIntrinsicName,
+ tree->AsIntrinsic()->gtMethodHandle R2RARG(tree->AsIntrinsic()->gtEntryPoint));
break;
case GT_BOUNDS_CHECK:
@@ -9711,6 +9716,12 @@ GenTree* Compiler::gtCloneExpr(GenTree* tree)
tree->AsHWIntrinsic()->GetHWIntrinsicId(),
tree->AsHWIntrinsic()->GetSimdBaseJitType(), tree->AsHWIntrinsic()->GetSimdSize());
copy->AsHWIntrinsic()->SetAuxiliaryJitType(tree->AsHWIntrinsic()->GetAuxiliaryJitType());
+
+ if (tree->AsHWIntrinsic()->IsUserCall())
+ {
+ copy->AsHWIntrinsic()->SetMethodHandle(this, tree->AsHWIntrinsic()->GetMethodHandle()
+ R2RARG(tree->AsHWIntrinsic()->GetEntryPoint()));
+ }
goto CLONE_MULTIOP_OPERANDS;
#endif
#if defined(FEATURE_SIMD) || defined(FEATURE_HW_INTRINSICS)
@@ -18269,6 +18280,79 @@ unsigned GenTreeVecCon::ElementCount(unsigned simdSize, var_types simdBaseType)
{
return simdSize / genTypeSize(simdBaseType);
}
+
+bool Compiler::IsValidForShuffle(GenTreeVecCon* vecCon, unsigned simdSize, var_types simdBaseType) const
+{
+#if defined(TARGET_XARCH)
+ size_t elementSize = genTypeSize(simdBaseType);
+ size_t elementCount = simdSize / elementSize;
+
+ if (simdSize == 32)
+ {
+ if (!compOpportunisticallyDependsOn(InstructionSet_AVX2))
+ {
+ // While we could accelerate some functions on hardware with only AVX support
+ // it's likely not worth it overall given that IsHardwareAccelerated reports false
+ return false;
+ }
+ else if ((varTypeIsByte(simdBaseType) && !compOpportunisticallyDependsOn(InstructionSet_AVX512VBMI_VL)) ||
+ (varTypeIsShort(simdBaseType) && !compOpportunisticallyDependsOn(InstructionSet_AVX512BW_VL)))
+ {
+ bool crossLane = false;
+
+ for (size_t index = 0; index < elementCount; index++)
+ {
+ uint64_t value = vecCon->GetIntegralVectorConstElement(index, simdBaseType);
+
+ if (value >= elementCount)
+ {
+ continue;
+ }
+
+ if (index < (elementCount / 2))
+ {
+ if (value >= (elementCount / 2))
+ {
+ crossLane = true;
+ break;
+ }
+ }
+ else if (value < (elementCount / 2))
+ {
+ crossLane = true;
+ break;
+ }
+ }
+
+ if (crossLane)
+ {
+ // TODO-XARCH-CQ: We should emulate cross-lane shuffling for byte/sbyte and short/ushort
+ return false;
+ }
+ }
+ }
+ else if (simdSize == 64)
+ {
+ if (varTypeIsByte(simdBaseType) && !compOpportunisticallyDependsOn(InstructionSet_AVX512VBMI))
+ {
+ // TYP_BYTE, TYP_UBYTE need AVX512VBMI.
+ return false;
+ }
+ }
+ else
+ {
+ assert(simdSize == 16);
+
+ if (varTypeIsSmall(simdBaseType) && !compOpportunisticallyDependsOn(InstructionSet_SSSE3))
+ {
+ // TYP_BYTE, TYP_UBYTE, TYP_SHORT, and TYP_USHORT need SSSE3 to be able to shuffle any operation
+ return false;
+ }
+ }
+#endif // TARGET_XARCH
+
+ return true;
+}
#endif // FEATURE_HW_INTRINSICS*/
//------------------------------------------------------------------------
@@ -19570,6 +19654,49 @@ void GenTreeMultiOp::InitializeOperands(GenTree** operands, size_t operandCount)
SetOperandCount(operandCount);
}
+//------------------------------------------------------------------------
+// GenTreeJitIntrinsic::SetMethodHandle: Sets the method handle for an intrinsic
+// so that it can be rewritten back to a user call in a later phase
+//
+// Arguments:
+// comp - The compiler instance
+// methodHandle - The method handle representing the fallback handling for the intrinsic
+// entryPoint - The entry point information required for R2R scenarios
+//
+// Notes:
+// We need to ensure that the operands are not tracked inline so that we can track the
+// underlying method handle. See the comment in GenTreeJitIntrinsic around why the union
+// of fields exists.
+//
+void GenTreeJitIntrinsic::SetMethodHandle(Compiler* comp,
+ CORINFO_METHOD_HANDLE methodHandle R2RARG(CORINFO_CONST_LOOKUP entryPoint))
+{
+ assert(OperIsHWIntrinsic() && !IsUserCall());
+ gtFlags |= GTF_HW_USER_CALL;
+
+ size_t operandCount = GetOperandCount();
+
+ if ((operandCount != 0) && (operandCount <= ArrLen(gtInlineOperands)))
+ {
+ GenTree** oldOperands = GetOperandArray();
+ GenTree** newOperands = comp->getAllocator(CMK_ASTNode).allocate(operandCount);
+
+ ResetOperandArray(operandCount, comp, newOperands, operandCount);
+ assert(GetOperandArray() == newOperands);
+
+ for (size_t i = 0; i < operandCount; i++)
+ {
+ newOperands[i] = oldOperands[i];
+ }
+ }
+
+ gtMethodHandle = methodHandle;
+
+#if defined(FEATURE_READYTORUN)
+ gtEntryPoint = new (comp, CMK_ASTNode) CORINFO_CONST_LOOKUP(entryPoint);
+#endif // FEATURE_READYTORUN
+}
+
var_types GenTreeJitIntrinsic::GetAuxiliaryType() const
{
CorInfoType auxiliaryJitType = GetAuxiliaryJitType();
@@ -26361,7 +26488,7 @@ GenTreeFieldList* Compiler::gtConvertTableOpToFieldList(GenTree* op, unsigned fi
LclVarDsc* opVarDsc = lvaGetDesc(op->AsLclVar());
unsigned lclNum = lvaGetLclNum(opVarDsc);
unsigned fieldSize = opVarDsc->lvSize() / fieldCount;
- var_types fieldType = TYP_SIMD16;
+ var_types fieldType = Compiler::getSIMDTypeForSize(fieldSize);
GenTreeFieldList* fieldList = new (this, GT_FIELD_LIST) GenTreeFieldList();
int offset = 0;
@@ -26594,6 +26721,9 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoad(GenTree** pAddr) const
case NI_Sve_LoadVectorUInt16ZeroExtendToUInt64:
case NI_Sve_LoadVectorUInt32ZeroExtendToInt64:
case NI_Sve_LoadVectorUInt32ZeroExtendToUInt64:
+ case NI_Sve_Load2xVectorAndUnzip:
+ case NI_Sve_Load3xVectorAndUnzip:
+ case NI_Sve_Load4xVectorAndUnzip:
addr = Op(2);
break;
#endif // TARGET_ARM64
@@ -26712,8 +26842,10 @@ bool GenTreeHWIntrinsic::OperIsMemoryStore(GenTree** pAddr) const
case NI_Sve_StoreAndZipx3:
case NI_Sve_StoreAndZipx4:
case NI_Sve_StoreNarrowing:
+ case NI_Sve_StoreNonTemporal:
addr = Op(2);
break;
+
#endif // TARGET_ARM64
default:
@@ -27037,7 +27169,7 @@ bool GenTreeHWIntrinsic::OperRequiresCallFlag() const
}
}
- return false;
+ return IsUserCall();
}
//------------------------------------------------------------------------------
@@ -27116,6 +27248,13 @@ ClassLayout* GenTreeHWIntrinsic::GetLayout(Compiler* compiler) const
case NI_AdvSimd_Arm64_LoadAndReplicateToVector128x4:
return compiler->typGetBlkLayout(64);
+ case NI_Sve_Load2xVectorAndUnzip:
+ return compiler->typGetBlkLayout(compiler->getVectorTByteLength() * 2);
+ case NI_Sve_Load3xVectorAndUnzip:
+ return compiler->typGetBlkLayout(compiler->getVectorTByteLength() * 3);
+ case NI_Sve_Load4xVectorAndUnzip:
+ return compiler->typGetBlkLayout(compiler->getVectorTByteLength() * 4);
+
#endif // TARGET_ARM64
default:
diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h
index 6a1b50e1569c9..578b2f43b349b 100644
--- a/src/coreclr/jit/gentree.h
+++ b/src/coreclr/jit/gentree.h
@@ -559,6 +559,7 @@ enum GenTreeFlags : unsigned int
#ifdef FEATURE_HW_INTRINSICS
GTF_HW_EM_OP = 0x10000000, // GT_HWINTRINSIC -- node is used as an operand to an embedded mask
+ GTF_HW_USER_CALL = 0x20000000, // GT_HWINTRINSIC -- node is implemented via a user call
#endif // FEATURE_HW_INTRINSICS
};
@@ -5951,24 +5952,30 @@ struct GenTreeIntrinsic : public GenTreeOp
NamedIntrinsic gtIntrinsicName;
CORINFO_METHOD_HANDLE gtMethodHandle; // Method handle of the method which is treated as an intrinsic.
-#ifdef FEATURE_READYTORUN
+#if defined(FEATURE_READYTORUN)
// Call target lookup info for method call from a Ready To Run module
CORINFO_CONST_LOOKUP gtEntryPoint;
-#endif
+#endif // FEATURE_READYTORUN
- GenTreeIntrinsic(var_types type, GenTree* op1, NamedIntrinsic intrinsicName, CORINFO_METHOD_HANDLE methodHandle)
+ GenTreeIntrinsic(var_types type,
+ GenTree* op1,
+ NamedIntrinsic intrinsicName,
+ CORINFO_METHOD_HANDLE methodHandle R2RARG(CORINFO_CONST_LOOKUP entryPoint))
: GenTreeOp(GT_INTRINSIC, type, op1, nullptr)
, gtIntrinsicName(intrinsicName)
- , gtMethodHandle(methodHandle)
+ , gtMethodHandle(methodHandle) R2RARG(gtEntryPoint(entryPoint))
{
assert(intrinsicName != NI_Illegal);
}
- GenTreeIntrinsic(
- var_types type, GenTree* op1, GenTree* op2, NamedIntrinsic intrinsicName, CORINFO_METHOD_HANDLE methodHandle)
+ GenTreeIntrinsic(var_types type,
+ GenTree* op1,
+ GenTree* op2,
+ NamedIntrinsic intrinsicName,
+ CORINFO_METHOD_HANDLE methodHandle R2RARG(CORINFO_CONST_LOOKUP entryPoint))
: GenTreeOp(GT_INTRINSIC, type, op1, op2)
, gtIntrinsicName(intrinsicName)
- , gtMethodHandle(methodHandle)
+ , gtMethodHandle(methodHandle) R2RARG(gtEntryPoint(entryPoint))
{
assert(intrinsicName != NI_Illegal);
}
@@ -6089,6 +6096,15 @@ struct GenTreeMultiOp : public GenTree
}
#endif
+ bool IsUserCall() const
+ {
+#if defined(FEATURE_HW_INTRINSICS)
+ return OperIs(GT_HWINTRINSIC) && (gtFlags & GTF_HW_USER_CALL) != 0;
+#else
+ return false;
+#endif
+ }
+
GenTree*& Op(size_t index)
{
size_t actualIndex = index - 1;
@@ -6217,7 +6233,29 @@ class IntrinsicNodeBuilder final
struct GenTreeJitIntrinsic : public GenTreeMultiOp
{
protected:
- GenTree* gtInlineOperands[2];
+ union
+ {
+ // We don't have enough space to carry both the inline operands
+ // and the necessary information required to support rewriting
+ // the intrinsic back into a user call. As such, we union the
+ // data instead and use the GTF_HW_USER_CALL flag to indicate
+ // which fields are valid to access. -- Tracking the fields
+ // independently causes TREE_NODE_SZ_LARGE to increase and for
+ // GenTreeJitIntrinsic to become the largest node, which is
+ // undesirable, so this approach helps keep things pay-for-play.
+
+ GenTree* gtInlineOperands[2];
+
+ struct
+ {
+ CORINFO_METHOD_HANDLE gtMethodHandle;
+
+#if defined(FEATURE_READYTORUN)
+ // Call target lookup info for method call from a Ready To Run module
+ CORINFO_CONST_LOOKUP* gtEntryPoint;
+#endif // FEATURE_READYTORUN
+ };
+ };
regNumberSmall gtOtherReg; // The second register for multi-reg intrinsics.
MultiRegSpillFlags gtSpillFlags; // Spill flags for multi-reg intrinsics.
unsigned char gtAuxiliaryJitType; // For intrinsics than need another type (e.g. Avx2.Gather* or SIMD (by element))
@@ -6226,6 +6264,22 @@ struct GenTreeJitIntrinsic : public GenTreeMultiOp
NamedIntrinsic gtHWIntrinsicId;
public:
+ CORINFO_METHOD_HANDLE GetMethodHandle() const
+ {
+ assert(IsUserCall());
+ return gtMethodHandle;
+ }
+
+ void SetMethodHandle(Compiler* comp, CORINFO_METHOD_HANDLE methodHandle R2RARG(CORINFO_CONST_LOOKUP entryPoint));
+
+#if defined(FEATURE_READYTORUN)
+ CORINFO_CONST_LOOKUP GetEntryPoint() const
+ {
+ assert(IsUserCall());
+ return *gtEntryPoint;
+ }
+#endif // FEATURE_READYTORUN
+
//-----------------------------------------------------------
// GetRegNumByIdx: Get regNumber of i'th position.
//
diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp
index e6b0e5fa72ffb..48dd3cffa1046 100644
--- a/src/coreclr/jit/hwintrinsic.cpp
+++ b/src/coreclr/jit/hwintrinsic.cpp
@@ -1131,6 +1131,7 @@ bool Compiler::CheckHWIntrinsicImmRange(NamedIntrinsic intrinsic,
// clsHnd -- class handle containing the intrinsic function.
// method -- method handle of the intrinsic function.
// sig -- signature of the intrinsic call
+// entryPoint -- The entry point information required for R2R scenarios
// mustExpand -- true if the intrinsic must return a GenTree*; otherwise, false
// Return Value:
@@ -1139,7 +1140,7 @@ bool Compiler::CheckHWIntrinsicImmRange(NamedIntrinsic intrinsic,
GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
CORINFO_CLASS_HANDLE clsHnd,
CORINFO_METHOD_HANDLE method,
- CORINFO_SIG_INFO* sig,
+ CORINFO_SIG_INFO* sig R2RARG(CORINFO_CONST_LOOKUP* entryPoint),
bool mustExpand)
{
// NextCallRetAddr requires a CALL, so return nullptr.
@@ -1241,7 +1242,27 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
unsigned int sizeBytes;
simdBaseJitType = getBaseJitTypeAndSizeOfSIMDType(clsHnd, &sizeBytes);
- assert((category == HW_Category_Special) || (category == HW_Category_Helper) || (sizeBytes != 0));
+
+#if defined(TARGET_ARM64)
+ if (simdBaseJitType == CORINFO_TYPE_UNDEF && HWIntrinsicInfo::HasScalarInputVariant(intrinsic))
+ {
+ // Did not find a valid vector type. The intrinsic has alternate scalar version. Switch to that.
+
+ assert(sizeBytes == 0);
+ intrinsic = HWIntrinsicInfo::GetScalarInputVariant(intrinsic);
+ category = HWIntrinsicInfo::lookupCategory(intrinsic);
+ isa = HWIntrinsicInfo::lookupIsa(intrinsic);
+
+ simdBaseJitType = sig->retType;
+ assert(simdBaseJitType != CORINFO_TYPE_VOID);
+ assert(simdBaseJitType != CORINFO_TYPE_UNDEF);
+ assert(simdBaseJitType != CORINFO_TYPE_VALUECLASS);
+ }
+ else
+#endif
+ {
+ assert((category == HW_Category_Special) || (category == HW_Category_Helper) || (sizeBytes != 0));
+ }
}
}
@@ -1270,6 +1291,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
int immUpperBound = 0;
bool hasFullRangeImm = false;
bool useFallback = false;
+ bool setMethodHandle = false;
getHWIntrinsicImmOps(intrinsic, sig, &immOp1, &immOp2);
@@ -1286,7 +1308,20 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
if (!CheckHWIntrinsicImmRange(intrinsic, simdBaseJitType, immOp2, mustExpand, immLowerBound, immUpperBound,
false, &useFallback))
{
- return useFallback ? impNonConstFallback(intrinsic, retType, simdBaseJitType) : nullptr;
+ if (useFallback)
+ {
+ return impNonConstFallback(intrinsic, retType, simdBaseJitType);
+ }
+ else if (!opts.OptimizationEnabled())
+ {
+ // Only enable late stage rewriting if optimizations are enabled
+ // as we won't otherwise encounter a constant at the later point
+ return nullptr;
+ }
+ else
+ {
+ setMethodHandle = true;
+ }
}
}
#else
@@ -1310,7 +1345,20 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
if (!CheckHWIntrinsicImmRange(intrinsic, simdBaseJitType, immOp1, mustExpand, immLowerBound, immUpperBound,
hasFullRangeImm, &useFallback))
{
- return useFallback ? impNonConstFallback(intrinsic, retType, simdBaseJitType) : nullptr;
+ if (useFallback)
+ {
+ return impNonConstFallback(intrinsic, retType, simdBaseJitType);
+ }
+ else if (!opts.OptimizationEnabled())
+ {
+ // Only enable late stage rewriting if optimizations are enabled
+ // as we won't otherwise encounter a constant at the later point
+ return nullptr;
+ }
+ else
+ {
+ setMethodHandle = true;
+ }
}
}
@@ -1577,8 +1625,13 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
}
else
{
- retNode =
- impSpecialIntrinsic(intrinsic, clsHnd, method, sig, simdBaseJitType, nodeRetType, simdSize, mustExpand);
+ retNode = impSpecialIntrinsic(intrinsic, clsHnd, method, sig R2RARG(entryPoint), simdBaseJitType, nodeRetType,
+ simdSize, mustExpand);
+ }
+
+ if (setMethodHandle && (retNode != nullptr))
+ {
+ retNode->AsHWIntrinsic()->SetMethodHandle(this, method R2RARG(*entryPoint));
}
#if defined(TARGET_ARM64)
@@ -1597,12 +1650,31 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
return retNode->AsHWIntrinsic()->Op(3);
}
}
+ else if (intrinsic == NI_Sve_GetActiveElementCount)
+ {
+ GenTree* op2 = retNode->AsHWIntrinsic()->Op(2);
+
+ // HWInstrinsic requires a mask for op2
+ if (!varTypeIsMask(op2))
+ {
+ retNode->AsHWIntrinsic()->Op(2) =
+ gtNewSimdConvertVectorToMaskNode(retType, op2, simdBaseJitType, simdSize);
+ }
+ }
if (!varTypeIsMask(op1))
{
// Op1 input is a vector. HWInstrinsic requires a mask.
retNode->AsHWIntrinsic()->Op(1) = gtNewSimdConvertVectorToMaskNode(retType, op1, simdBaseJitType, simdSize);
}
+
+ if (HWIntrinsicInfo::IsMultiReg(intrinsic))
+ {
+ assert(HWIntrinsicInfo::IsExplicitMaskedOperation(retNode->AsHWIntrinsic()->GetHWIntrinsicId()));
+ assert(HWIntrinsicInfo::IsMultiReg(retNode->AsHWIntrinsic()->GetHWIntrinsicId()));
+ retNode =
+ impStoreMultiRegValueToVar(retNode, sig->retTypeSigClass DEBUGARG(CorInfoCallConvExtension::Managed));
+ }
}
if (retType != nodeRetType)
diff --git a/src/coreclr/jit/hwintrinsic.h b/src/coreclr/jit/hwintrinsic.h
index 16c5b770ada4a..e156ef3544cd3 100644
--- a/src/coreclr/jit/hwintrinsic.h
+++ b/src/coreclr/jit/hwintrinsic.h
@@ -232,10 +232,14 @@ enum HWIntrinsicFlag : unsigned int
// The intrinsic has an enum operand. Using this implies HW_Flag_HasImmediateOperand.
HW_Flag_HasEnumOperand = 0x1000000,
+ // The intrinsic comes in both vector and scalar variants. During the import stage if the basetype is scalar,
+ // then the intrinsic should be switched to a scalar only version.
+ HW_Flag_HasScalarInputVariant = 0x2000000,
+
#endif // TARGET_XARCH
// The intrinsic is a FusedMultiplyAdd intrinsic
- HW_Flag_FmaIntrinsic = 0x20000000,
+ HW_Flag_FmaIntrinsic = 0x40000000,
#if defined(TARGET_ARM64)
// The intrinsic uses a mask in arg1 to select elements present in the result, and must use a low vector register.
@@ -831,6 +835,7 @@ struct HWIntrinsicInfo
case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x2:
case NI_AdvSimd_LoadAndReplicateToVector64x2:
case NI_AdvSimd_Arm64_LoadAndReplicateToVector128x2:
+ case NI_Sve_Load2xVectorAndUnzip:
return 2;
case NI_AdvSimd_LoadVector64x3AndUnzip:
@@ -841,6 +846,7 @@ struct HWIntrinsicInfo
case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x3:
case NI_AdvSimd_LoadAndReplicateToVector64x3:
case NI_AdvSimd_Arm64_LoadAndReplicateToVector128x3:
+ case NI_Sve_Load3xVectorAndUnzip:
return 3;
case NI_AdvSimd_LoadVector64x4AndUnzip:
@@ -851,6 +857,7 @@ struct HWIntrinsicInfo
case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4:
case NI_AdvSimd_LoadAndReplicateToVector64x4:
case NI_AdvSimd_Arm64_LoadAndReplicateToVector128x4:
+ case NI_Sve_Load4xVectorAndUnzip:
return 4;
#endif
@@ -926,6 +933,41 @@ struct HWIntrinsicInfo
return (flags & HW_Flag_HasEnumOperand) != 0;
}
+ static bool HasScalarInputVariant(NamedIntrinsic id)
+ {
+ const HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_HasScalarInputVariant) != 0;
+ }
+
+ static NamedIntrinsic GetScalarInputVariant(NamedIntrinsic id)
+ {
+ assert(HasScalarInputVariant(id));
+
+ switch (id)
+ {
+ case NI_Sve_SaturatingDecrementBy16BitElementCount:
+ return NI_Sve_SaturatingDecrementBy16BitElementCountScalar;
+
+ case NI_Sve_SaturatingDecrementBy32BitElementCount:
+ return NI_Sve_SaturatingDecrementBy32BitElementCountScalar;
+
+ case NI_Sve_SaturatingDecrementBy64BitElementCount:
+ return NI_Sve_SaturatingDecrementBy64BitElementCountScalar;
+
+ case NI_Sve_SaturatingIncrementBy16BitElementCount:
+ return NI_Sve_SaturatingIncrementBy16BitElementCountScalar;
+
+ case NI_Sve_SaturatingIncrementBy32BitElementCount:
+ return NI_Sve_SaturatingIncrementBy32BitElementCountScalar;
+
+ case NI_Sve_SaturatingIncrementBy64BitElementCount:
+ return NI_Sve_SaturatingIncrementBy64BitElementCountScalar;
+
+ default:
+ unreached();
+ }
+ }
+
#endif // TARGET_ARM64
static bool HasSpecialSideEffect(NamedIntrinsic id)
@@ -965,6 +1007,66 @@ struct HWIntrinsicInfo
return (flags & HW_Flag_PermuteVar2x) != 0;
}
#endif // TARGET_XARCH
+
+#if defined(TARGET_ARM64)
+ static void GetImmOpsPositions(NamedIntrinsic id, CORINFO_SIG_INFO* sig, int* imm1Pos, int* imm2Pos)
+ {
+ switch (id)
+ {
+ case NI_AdvSimd_Insert:
+ case NI_AdvSimd_InsertScalar:
+ case NI_AdvSimd_LoadAndInsertScalar:
+ case NI_AdvSimd_LoadAndInsertScalarVector64x2:
+ case NI_AdvSimd_LoadAndInsertScalarVector64x3:
+ case NI_AdvSimd_LoadAndInsertScalarVector64x4:
+ case NI_AdvSimd_Arm64_LoadAndInsertScalar:
+ case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x2:
+ case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x3:
+ case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4:
+ {
+ assert(sig->numArgs == 3);
+ *imm1Pos = 1;
+ break;
+ }
+
+ case NI_AdvSimd_Arm64_InsertSelectedScalar:
+ {
+ assert(sig->numArgs == 4);
+ *imm1Pos = 2;
+ *imm2Pos = 0;
+ break;
+ }
+
+ case NI_Sve_SaturatingDecrementBy16BitElementCount:
+ case NI_Sve_SaturatingDecrementBy32BitElementCount:
+ case NI_Sve_SaturatingDecrementBy64BitElementCount:
+ case NI_Sve_SaturatingDecrementBy8BitElementCount:
+ case NI_Sve_SaturatingIncrementBy16BitElementCount:
+ case NI_Sve_SaturatingIncrementBy32BitElementCount:
+ case NI_Sve_SaturatingIncrementBy64BitElementCount:
+ case NI_Sve_SaturatingIncrementBy8BitElementCount:
+ case NI_Sve_SaturatingDecrementBy16BitElementCountScalar:
+ case NI_Sve_SaturatingDecrementBy32BitElementCountScalar:
+ case NI_Sve_SaturatingDecrementBy64BitElementCountScalar:
+ case NI_Sve_SaturatingIncrementBy16BitElementCountScalar:
+ case NI_Sve_SaturatingIncrementBy32BitElementCountScalar:
+ case NI_Sve_SaturatingIncrementBy64BitElementCountScalar:
+ {
+ assert(sig->numArgs == 3);
+ *imm1Pos = 1;
+ *imm2Pos = 0;
+ break;
+ }
+
+ default:
+ {
+ assert(sig->numArgs > 0);
+ *imm1Pos = 0;
+ break;
+ }
+ }
+ }
+#endif // TARGET_ARM64
};
#ifdef TARGET_ARM64
diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp
index ec4bc0ee5dd95..095f31246d0c6 100644
--- a/src/coreclr/jit/hwintrinsicarm64.cpp
+++ b/src/coreclr/jit/hwintrinsicarm64.cpp
@@ -233,33 +233,7 @@ void Compiler::getHWIntrinsicImmOps(NamedIntrinsic intrinsic,
int imm1Pos = -1;
int imm2Pos = -1;
- switch (intrinsic)
- {
- case NI_AdvSimd_Insert:
- case NI_AdvSimd_InsertScalar:
- case NI_AdvSimd_LoadAndInsertScalar:
- case NI_AdvSimd_LoadAndInsertScalarVector64x2:
- case NI_AdvSimd_LoadAndInsertScalarVector64x3:
- case NI_AdvSimd_LoadAndInsertScalarVector64x4:
- case NI_AdvSimd_Arm64_LoadAndInsertScalar:
- case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x2:
- case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x3:
- case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4:
- assert(sig->numArgs == 3);
- imm1Pos = 1;
- break;
-
- case NI_AdvSimd_Arm64_InsertSelectedScalar:
- assert(sig->numArgs == 4);
- imm1Pos = 2;
- imm2Pos = 0;
- break;
-
- default:
- assert(sig->numArgs > 0);
- imm1Pos = 0;
- break;
- }
+ HWIntrinsicInfo::GetImmOpsPositions(intrinsic, sig, &imm1Pos, &imm2Pos);
if (imm1Pos >= 0)
{
@@ -447,6 +421,33 @@ void HWIntrinsicInfo::lookupImmBounds(
immUpperBound = (int)SVE_PATTERN_ALL;
break;
+ case NI_Sve_SaturatingDecrementBy16BitElementCount:
+ case NI_Sve_SaturatingDecrementBy32BitElementCount:
+ case NI_Sve_SaturatingDecrementBy64BitElementCount:
+ case NI_Sve_SaturatingDecrementBy8BitElementCount:
+ case NI_Sve_SaturatingIncrementBy16BitElementCount:
+ case NI_Sve_SaturatingIncrementBy32BitElementCount:
+ case NI_Sve_SaturatingIncrementBy64BitElementCount:
+ case NI_Sve_SaturatingIncrementBy8BitElementCount:
+ case NI_Sve_SaturatingDecrementBy16BitElementCountScalar:
+ case NI_Sve_SaturatingDecrementBy32BitElementCountScalar:
+ case NI_Sve_SaturatingDecrementBy64BitElementCountScalar:
+ case NI_Sve_SaturatingIncrementBy16BitElementCountScalar:
+ case NI_Sve_SaturatingIncrementBy32BitElementCountScalar:
+ case NI_Sve_SaturatingIncrementBy64BitElementCountScalar:
+ if (immNumber == 1)
+ {
+ immLowerBound = 1;
+ immUpperBound = 16;
+ }
+ else
+ {
+ assert(immNumber == 2);
+ immLowerBound = (int)SVE_PATTERN_POW2;
+ immUpperBound = (int)SVE_PATTERN_ALL;
+ }
+ break;
+
default:
unreached();
}
@@ -482,6 +483,7 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdT
// clsHnd -- class handle containing the intrinsic function.
// method -- method handle of the intrinsic function.
// sig -- signature of the intrinsic call.
+// entryPoint -- The entry point information required for R2R scenarios
// simdBaseJitType -- generic argument of the intrinsic.
// retType -- return type of the intrinsic.
// mustExpand -- true if the intrinsic must return a GenTree*; otherwise, false
@@ -492,7 +494,7 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdT
GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
CORINFO_CLASS_HANDLE clsHnd,
CORINFO_METHOD_HANDLE method,
- CORINFO_SIG_INFO* sig,
+ CORINFO_SIG_INFO* sig R2RARG(CORINFO_CONST_LOOKUP* entryPoint),
CorInfoType simdBaseJitType,
var_types retType,
unsigned simdSize,
@@ -512,7 +514,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
return gtNewScalarHWIntrinsicNode(TYP_VOID, intrinsic);
}
- assert(category != HW_Category_Scalar);
+ bool isScalar = (category == HW_Category_Scalar);
assert(!HWIntrinsicInfo::isScalarIsa(HWIntrinsicInfo::lookupIsa(intrinsic)));
assert(numArgs >= 0);
@@ -526,6 +528,10 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
GenTree* op3 = nullptr;
GenTree* op4 = nullptr;
+#ifdef DEBUG
+ bool isValidScalarIntrinsic = false;
+#endif
+
switch (intrinsic)
{
case NI_Vector64_Abs:
@@ -537,8 +543,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector64_Add:
- case NI_Vector128_Add:
case NI_Vector64_op_Addition:
case NI_Vector128_op_Addition:
{
@@ -563,34 +567,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector64_As:
- case NI_Vector64_AsByte:
- case NI_Vector64_AsDouble:
- case NI_Vector64_AsInt16:
- case NI_Vector64_AsInt32:
- case NI_Vector64_AsInt64:
- case NI_Vector64_AsNInt:
- case NI_Vector64_AsNUInt:
- case NI_Vector64_AsSByte:
- case NI_Vector64_AsSingle:
- case NI_Vector64_AsUInt16:
- case NI_Vector64_AsUInt32:
- case NI_Vector64_AsUInt64:
- case NI_Vector128_As:
- case NI_Vector128_AsByte:
- case NI_Vector128_AsDouble:
- case NI_Vector128_AsInt16:
- case NI_Vector128_AsInt32:
- case NI_Vector128_AsInt64:
- case NI_Vector128_AsNInt:
- case NI_Vector128_AsNUInt:
- case NI_Vector128_AsSByte:
- case NI_Vector128_AsSingle:
- case NI_Vector128_AsUInt16:
- case NI_Vector128_AsUInt32:
- case NI_Vector128_AsUInt64:
case NI_Vector128_AsVector:
- case NI_Vector128_AsVector4:
{
assert(!sig->hasThis());
assert(numArgs == 1);
@@ -705,8 +682,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector64_BitwiseAnd:
- case NI_Vector128_BitwiseAnd:
case NI_Vector64_op_BitwiseAnd:
case NI_Vector128_op_BitwiseAnd:
{
@@ -719,8 +694,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector64_BitwiseOr:
- case NI_Vector128_BitwiseOr:
case NI_Vector64_op_BitwiseOr:
case NI_Vector128_op_BitwiseOr:
{
@@ -1089,8 +1062,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector64_Divide:
- case NI_Vector128_Divide:
case NI_Vector64_op_Division:
case NI_Vector128_op_Division:
{
@@ -1147,8 +1118,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector64_EqualsAll:
- case NI_Vector128_EqualsAll:
case NI_Vector64_op_Equality:
case NI_Vector128_op_Equality:
{
@@ -1394,14 +1363,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector64_get_Zero:
- case NI_Vector128_get_Zero:
- {
- assert(sig->numArgs == 0);
- retNode = gtNewZeroConNode(retType);
- break;
- }
-
case NI_Vector64_GetElement:
case NI_Vector128_GetElement:
{
@@ -1587,8 +1548,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
case NI_AdvSimd_LoadVector64:
case NI_AdvSimd_LoadVector128:
- case NI_Vector64_Load:
- case NI_Vector128_Load:
case NI_Vector64_LoadUnsafe:
case NI_Vector128_LoadUnsafe:
{
@@ -1694,8 +1653,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector64_Multiply:
- case NI_Vector128_Multiply:
case NI_Vector64_op_Multiply:
case NI_Vector128_op_Multiply:
{
@@ -1759,8 +1716,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector64_Negate:
- case NI_Vector128_Negate:
case NI_Vector64_op_UnaryNegation:
case NI_Vector128_op_UnaryNegation:
{
@@ -1770,8 +1725,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector64_OnesComplement:
- case NI_Vector128_OnesComplement:
case NI_Vector64_op_OnesComplement:
case NI_Vector128_op_OnesComplement:
{
@@ -1794,16 +1747,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector64_op_UnaryPlus:
- case NI_Vector128_op_UnaryPlus:
- {
- assert(sig->numArgs == 1);
- retNode = impSIMDPopStack();
- break;
- }
-
- case NI_Vector64_Subtract:
- case NI_Vector128_Subtract:
case NI_Vector64_op_Subtraction:
case NI_Vector128_op_Subtraction:
{
@@ -1816,8 +1759,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector64_ShiftLeft:
- case NI_Vector128_ShiftLeft:
case NI_Vector64_op_LeftShift:
case NI_Vector128_op_LeftShift:
{
@@ -1830,8 +1771,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector64_ShiftRightArithmetic:
- case NI_Vector128_ShiftRightArithmetic:
case NI_Vector64_op_RightShift:
case NI_Vector128_op_RightShift:
{
@@ -1845,8 +1784,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector64_ShiftRightLogical:
- case NI_Vector128_ShiftRightLogical:
case NI_Vector64_op_UnsignedRightShift:
case NI_Vector128_op_UnsignedRightShift:
{
@@ -1867,9 +1804,23 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
GenTree* indices = impStackTop(0).val;
- if (!indices->IsVectorConst())
+ if (!indices->IsVectorConst() || !IsValidForShuffle(indices->AsVecCon(), simdSize, simdBaseType))
{
- // TODO-ARM64-CQ: Handling non-constant indices is a bit more complex
+ assert(sig->numArgs == 2);
+
+ if (!opts.OptimizationEnabled())
+ {
+ // Only enable late stage rewriting if optimizations are enabled
+ // as we won't otherwise encounter a constant at the later point
+ return nullptr;
+ }
+
+ op2 = impSIMDPopStack();
+ op1 = impSIMDPopStack();
+
+ retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize);
+
+ retNode->AsHWIntrinsic()->SetMethodHandle(this, method R2RARG(*entryPoint));
break;
}
@@ -1916,9 +1867,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector64_Store:
case NI_Vector64_StoreUnsafe:
- case NI_Vector128_Store:
case NI_Vector128_StoreUnsafe:
{
assert(retType == TYP_VOID);
@@ -2084,6 +2033,13 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
assert(sig->numArgs == 3);
assert(retType == TYP_VOID);
+ if (!mustExpand && !impStackTop(0).val->IsCnsIntOrI() && (impStackTop(1).val->TypeGet() == TYP_STRUCT))
+ {
+ // TODO-ARM64-CQ: Support rewriting nodes that involves
+ // GenTreeFieldList as user calls during rationalization
+ return nullptr;
+ }
+
CORINFO_ARG_LIST_HANDLE arg1 = sig->args;
CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(arg1);
CORINFO_ARG_LIST_HANDLE arg3 = info.compCompHnd->getArgNext(arg2);
@@ -2195,9 +2151,21 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
if (!indexOp->OperIsConst())
{
- // TODO-ARM64-CQ: We should always import these like we do with GetElement
- // If index is not constant use software fallback.
- return nullptr;
+ if (!opts.OptimizationEnabled())
+ {
+ // Only enable late stage rewriting if optimizations are enabled
+ // as we won't otherwise encounter a constant at the later point
+ return nullptr;
+ }
+
+ op3 = impPopStack().val;
+ op2 = impPopStack().val;
+ op1 = impSIMDPopStack();
+
+ retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, op3, intrinsic, simdBaseJitType, simdSize);
+
+ retNode->AsHWIntrinsic()->SetMethodHandle(this, method R2RARG(*entryPoint));
+ break;
}
ssize_t imm8 = indexOp->AsIntCon()->IconValue();
@@ -2237,8 +2205,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector64_Xor:
- case NI_Vector128_Xor:
case NI_Vector64_op_ExclusiveOr:
case NI_Vector128_op_ExclusiveOr:
{
@@ -2296,6 +2262,35 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
retNode = impStoreMultiRegValueToVar(op1, sig->retTypeSigClass DEBUGARG(CorInfoCallConvExtension::Managed));
break;
}
+
+ case NI_Sve_Load2xVectorAndUnzip:
+ case NI_Sve_Load3xVectorAndUnzip:
+ case NI_Sve_Load4xVectorAndUnzip:
+ {
+ info.compNeedsConsecutiveRegisters = true;
+
+ assert(sig->numArgs == 2);
+
+ op2 = impPopStack().val;
+ op1 = impPopStack().val;
+
+ if (op2->OperIs(GT_CAST))
+ {
+ // Although the API specifies a pointer, if what we have is a BYREF, that's what
+ // we really want, so throw away the cast.
+ if (op2->gtGetOp1()->TypeGet() == TYP_BYREF)
+ {
+ op2 = op2->gtGetOp1();
+ }
+ }
+
+ assert(HWIntrinsicInfo::IsMultiReg(intrinsic));
+ assert(HWIntrinsicInfo::IsExplicitMaskedOperation(intrinsic));
+
+ retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize);
+ break;
+ }
+
case NI_AdvSimd_LoadAndInsertScalarVector64x2:
case NI_AdvSimd_LoadAndInsertScalarVector64x3:
case NI_AdvSimd_LoadAndInsertScalarVector64x4:
@@ -2305,6 +2300,13 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
{
assert(sig->numArgs == 3);
+ if (!mustExpand && !impStackTop(1).val->IsCnsIntOrI())
+ {
+ // TODO-ARM64-CQ: Support rewriting nodes that involves
+ // GenTreeFieldList as user calls during rationalization
+ return nullptr;
+ }
+
CORINFO_ARG_LIST_HANDLE arg1 = sig->args;
CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(arg1);
CORINFO_ARG_LIST_HANDLE arg3 = info.compCompHnd->getArgNext(arg2);
@@ -2436,6 +2438,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
CORINFO_ARG_LIST_HANDLE arg3 = info.compCompHnd->getArgNext(arg2);
var_types argType = TYP_UNKNOWN;
CORINFO_CLASS_HANDLE argClass = NO_CLASS_HANDLE;
+
argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg3, &argClass)));
op3 = impPopStack().val;
unsigned fieldCount = info.compCompHnd->getClassNumInstanceFields(argClass);
@@ -2507,12 +2510,96 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
+ case NI_Sve_SaturatingDecrementBy8BitElementCount:
+ case NI_Sve_SaturatingIncrementBy8BitElementCount:
+ case NI_Sve_SaturatingDecrementBy16BitElementCountScalar:
+ case NI_Sve_SaturatingDecrementBy32BitElementCountScalar:
+ case NI_Sve_SaturatingDecrementBy64BitElementCountScalar:
+ case NI_Sve_SaturatingIncrementBy16BitElementCountScalar:
+ case NI_Sve_SaturatingIncrementBy32BitElementCountScalar:
+ case NI_Sve_SaturatingIncrementBy64BitElementCountScalar:
+#ifdef DEBUG
+ isValidScalarIntrinsic = true;
+ FALLTHROUGH;
+#endif
+ case NI_Sve_SaturatingDecrementBy16BitElementCount:
+ case NI_Sve_SaturatingDecrementBy32BitElementCount:
+ case NI_Sve_SaturatingDecrementBy64BitElementCount:
+ case NI_Sve_SaturatingIncrementBy16BitElementCount:
+ case NI_Sve_SaturatingIncrementBy32BitElementCount:
+ case NI_Sve_SaturatingIncrementBy64BitElementCount:
+
+ {
+ assert(sig->numArgs == 3);
+
+ CORINFO_ARG_LIST_HANDLE arg1 = sig->args;
+ CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(arg1);
+ CORINFO_ARG_LIST_HANDLE arg3 = info.compCompHnd->getArgNext(arg2);
+ var_types argType = TYP_UNKNOWN;
+ CORINFO_CLASS_HANDLE argClass = NO_CLASS_HANDLE;
+ int immLowerBound = 0;
+ int immUpperBound = 0;
+
+ argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg3, &argClass)));
+ op3 = getArgForHWIntrinsic(argType, argClass);
+ argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass)));
+ op2 = getArgForHWIntrinsic(argType, argClass);
+ argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg1, &argClass)));
+ op1 = impPopStack().val;
+
+ assert(HWIntrinsicInfo::isImmOp(intrinsic, op2));
+ HWIntrinsicInfo::lookupImmBounds(intrinsic, simdSize, simdBaseType, 1, &immLowerBound, &immUpperBound);
+ op2 = addRangeCheckIfNeeded(intrinsic, op2, (!op2->IsCnsIntOrI()), immLowerBound, immUpperBound);
+
+ assert(HWIntrinsicInfo::isImmOp(intrinsic, op3));
+ HWIntrinsicInfo::lookupImmBounds(intrinsic, simdSize, simdBaseType, 2, &immLowerBound, &immUpperBound);
+ op3 = addRangeCheckIfNeeded(intrinsic, op3, (!op3->IsCnsIntOrI()), immLowerBound, immUpperBound);
+
+ retNode = isScalar ? gtNewScalarHWIntrinsicNode(retType, op1, op2, op3, intrinsic)
+ : gtNewSimdHWIntrinsicNode(retType, op1, op2, op3, intrinsic, simdBaseJitType, simdSize);
+
+ retNode->AsHWIntrinsic()->SetSimdBaseJitType(simdBaseJitType);
+ break;
+ }
+
+ case NI_Sve_SaturatingDecrementByActiveElementCount:
+ case NI_Sve_SaturatingIncrementByActiveElementCount:
+ {
+ assert(sig->numArgs == 2);
+
+ CORINFO_ARG_LIST_HANDLE arg1 = sig->args;
+ CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(arg1);
+ var_types argType = TYP_UNKNOWN;
+ CORINFO_CLASS_HANDLE argClass = NO_CLASS_HANDLE;
+
+ argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass)));
+ op2 = getArgForHWIntrinsic(argType, argClass);
+ argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg1, &argClass)));
+ op1 = impPopStack().val;
+
+ CorInfoType op1BaseJitType = getBaseJitTypeOfSIMDType(argClass);
+
+ // HWInstrinsic requires a mask for op2
+ if (!varTypeIsMask(op2))
+ {
+ op2 = gtNewSimdConvertVectorToMaskNode(retType, op2, simdBaseJitType, simdSize);
+ }
+
+ retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize);
+
+ retNode->AsHWIntrinsic()->SetSimdBaseJitType(simdBaseJitType);
+ retNode->AsHWIntrinsic()->SetAuxiliaryJitType(op1BaseJitType);
+ break;
+ }
+
default:
{
return nullptr;
}
}
+ assert(!isScalar || isValidScalarIntrinsic);
+
return retNode;
}
diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp
index 9536405b8ad29..23b09c0cef751 100644
--- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp
+++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp
@@ -23,7 +23,6 @@
// codeGen -- an instance of CodeGen class.
// immOp -- an immediate operand of the intrinsic.
// intrin -- a hardware intrinsic tree node.
-// immNumber -- which immediate operand to use (most intrinsics only have one).
//
// Note: This class is designed to be used in the following way
// HWIntrinsicImmOpHelper helper(this, immOp, intrin);
@@ -36,10 +35,7 @@
// This allows to combine logic for cases when immOp->isContainedIntOrIImmed() is either true or false in a form
// of a for-loop.
//
-CodeGen::HWIntrinsicImmOpHelper::HWIntrinsicImmOpHelper(CodeGen* codeGen,
- GenTree* immOp,
- GenTreeHWIntrinsic* intrin,
- int immNumber /* = 1 */)
+CodeGen::HWIntrinsicImmOpHelper::HWIntrinsicImmOpHelper(CodeGen* codeGen, GenTree* immOp, GenTreeHWIntrinsic* intrin)
: codeGen(codeGen)
, endLabel(nullptr)
, nonZeroLabel(nullptr)
@@ -79,12 +75,12 @@ CodeGen::HWIntrinsicImmOpHelper::HWIntrinsicImmOpHelper(CodeGen* code
const unsigned int indexedElementSimdSize = genTypeSize(indexedElementOpType);
HWIntrinsicInfo::lookupImmBounds(intrin->GetHWIntrinsicId(), indexedElementSimdSize,
- intrin->GetSimdBaseType(), immNumber, &immLowerBound, &immUpperBound);
+ intrin->GetSimdBaseType(), 1, &immLowerBound, &immUpperBound);
}
else
{
HWIntrinsicInfo::lookupImmBounds(intrin->GetHWIntrinsicId(), intrin->GetSimdSize(),
- intrin->GetSimdBaseType(), immNumber, &immLowerBound, &immUpperBound);
+ intrin->GetSimdBaseType(), 1, &immLowerBound, &immUpperBound);
}
nonConstImmReg = immOp->GetRegNum();
@@ -109,6 +105,50 @@ CodeGen::HWIntrinsicImmOpHelper::HWIntrinsicImmOpHelper(CodeGen* code
}
}
+// HWIntrinsicImmOpHelper: Variant constructor of the helper class instance.
+// This is used when the immediate does not exist in a GenTree. For example, the immediate has been created
+// during codegen from other immediate values.
+//
+// Arguments:
+// codeGen -- an instance of CodeGen class.
+// immReg -- the register containing the immediate.
+// immLowerBound -- the lower bound of the register.
+// immUpperBound -- the lower bound of the register.
+// intrin -- a hardware intrinsic tree node.
+//
+// Note: This instance is designed to be used via the same for loop as the standard constructor.
+//
+CodeGen::HWIntrinsicImmOpHelper::HWIntrinsicImmOpHelper(
+ CodeGen* codeGen, regNumber immReg, int immLowerBound, int immUpperBound, GenTreeHWIntrinsic* intrin)
+ : codeGen(codeGen)
+ , endLabel(nullptr)
+ , nonZeroLabel(nullptr)
+ , immValue(immLowerBound)
+ , immLowerBound(immLowerBound)
+ , immUpperBound(immUpperBound)
+ , nonConstImmReg(immReg)
+ , branchTargetReg(REG_NA)
+{
+ assert(codeGen != nullptr);
+
+ if (TestImmOpZeroOrOne())
+ {
+ nonZeroLabel = codeGen->genCreateTempLabel();
+ }
+ else
+ {
+ // At the moment, this helper supports only intrinsics that correspond to one machine instruction.
+ // If we ever encounter an intrinsic that is either lowered into multiple instructions or
+ // the number of instructions that correspond to each case is unknown apriori - we can extend support to
+ // these by
+ // using the same approach as in hwintrinsicxarch.cpp - adding an additional indirection level in form of a
+ // branch table.
+ branchTargetReg = codeGen->internalRegisters.GetSingle(intrin);
+ }
+
+ endLabel = codeGen->genCreateTempLabel();
+}
+
//------------------------------------------------------------------------
// EmitBegin: emits the beginning of a "switch" table, no-op if an immediate operand is constant.
//
@@ -474,7 +514,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
opt);
}
}
- else if (targetReg == embMaskOp1Reg)
+ else if (emitter::isVectorRegister(embMaskOp1Reg) && (targetReg == embMaskOp1Reg))
{
// target != falseValue, but we do not want to overwrite target with `embMaskOp1Reg`.
// We will first do the predicate operation and then do conditionalSelect inactive
@@ -768,10 +808,17 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
else if (HWIntrinsicInfo::IsScalable(intrin.id))
{
assert(!node->IsEmbMaskOp());
- // This generates an unpredicated version
- // Predicated should be taken care above `intrin.op2->IsEmbMaskOp()`
- GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt,
- INS_SCALABLE_OPTS_UNPREDICATED);
+ if (HWIntrinsicInfo::IsExplicitMaskedOperation(intrin.id))
+ {
+ GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt);
+ }
+ else
+ {
+ // This generates an unpredicated version
+ // Implicitly predicated should be taken care above `intrin.op2->IsEmbMaskOp()`
+ GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt,
+ INS_SCALABLE_OPTS_UNPREDICATED);
+ }
}
else if (isRMW)
{
@@ -1360,6 +1407,26 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
}
break;
+ case NI_Sve_Load2xVectorAndUnzip:
+ case NI_Sve_Load3xVectorAndUnzip:
+ case NI_Sve_Load4xVectorAndUnzip:
+ {
+#ifdef DEBUG
+ // Validates that consecutive registers were used properly.
+
+ assert(node->GetMultiRegCount(compiler) == (unsigned int)GetEmitter()->insGetSveReg1ListSize(ins));
+
+ regNumber argReg = targetReg;
+ for (unsigned int i = 0; i < node->GetMultiRegCount(compiler); i++)
+ {
+ assert(argReg == node->GetRegNumByIdx(i));
+ argReg = getNextSIMDRegWithWraparound(argReg);
+ }
+#endif // DEBUG
+ GetEmitter()->emitIns_R_R_R_I(ins, emitSize, targetReg, op1Reg, op2Reg, 0, opt);
+ break;
+ }
+
case NI_Sve_StoreAndZipx2:
case NI_Sve_StoreAndZipx3:
case NI_Sve_StoreAndZipx4:
@@ -1416,6 +1483,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
}
case NI_Sve_StoreAndZip:
+ case NI_Sve_StoreNonTemporal:
{
GetEmitter()->emitIns_R_R_R_I(ins, emitSize, op3Reg, op1Reg, op2Reg, 0, opt);
break;
@@ -1777,11 +1845,18 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
break;
}
+ case NI_Sve_ReverseElement:
+ // Use non-predicated version explicitly
+ GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op1Reg, opt, INS_SCALABLE_OPTS_UNPREDICATED);
+ break;
+
case NI_Sve_StoreNarrowing:
opt = emitter::optGetSveInsOpt(emitTypeSize(intrin.baseType));
GetEmitter()->emitIns_R_R_R_I(ins, emitSize, op3Reg, op1Reg, op2Reg, 0, opt);
break;
+ case NI_Sve_TransposeEven:
+ case NI_Sve_TransposeOdd:
case NI_Sve_UnzipEven:
case NI_Sve_UnzipOdd:
case NI_Sve_ZipHigh:
@@ -1791,6 +1866,119 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
INS_SCALABLE_OPTS_UNPREDICATED);
break;
+ case NI_Sve_SaturatingDecrementBy16BitElementCountScalar:
+ case NI_Sve_SaturatingDecrementBy32BitElementCountScalar:
+ case NI_Sve_SaturatingDecrementBy64BitElementCountScalar:
+ case NI_Sve_SaturatingIncrementBy16BitElementCountScalar:
+ case NI_Sve_SaturatingIncrementBy32BitElementCountScalar:
+ case NI_Sve_SaturatingIncrementBy64BitElementCountScalar:
+ // Use scalar sizes.
+ emitSize = emitActualTypeSize(node->gtType);
+ opt = INS_OPTS_NONE;
+ FALLTHROUGH;
+
+ case NI_Sve_SaturatingDecrementBy16BitElementCount:
+ case NI_Sve_SaturatingDecrementBy32BitElementCount:
+ case NI_Sve_SaturatingDecrementBy64BitElementCount:
+ case NI_Sve_SaturatingDecrementBy8BitElementCount:
+ case NI_Sve_SaturatingIncrementBy16BitElementCount:
+ case NI_Sve_SaturatingIncrementBy32BitElementCount:
+ case NI_Sve_SaturatingIncrementBy64BitElementCount:
+ case NI_Sve_SaturatingIncrementBy8BitElementCount:
+ {
+ assert(isRMW);
+ if (targetReg != op1Reg)
+ {
+ assert(targetReg != op2Reg);
+ assert(targetReg != op3Reg);
+ GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true);
+ }
+
+ if (intrin.op2->IsCnsIntOrI() && intrin.op3->IsCnsIntOrI())
+ {
+ // Both immediates are constant, emit the intruction.
+
+ assert(intrin.op2->isContainedIntOrIImmed() && intrin.op3->isContainedIntOrIImmed());
+ int scale = (int)intrin.op2->AsIntCon()->gtIconVal;
+ insSvePattern pattern = (insSvePattern)intrin.op3->AsIntCon()->gtIconVal;
+ GetEmitter()->emitIns_R_PATTERN_I(ins, emitSize, targetReg, pattern, scale, opt);
+ }
+ else
+ {
+ // Use the helper to generate a table. The table can only use a single lookup value, therefore
+ // the two immediates scale (1 to 16, in op2Reg) and pattern (0 to 31, in op3reg) must be
+ // combined to a single value (0 to 511)
+
+ assert(!intrin.op2->isContainedIntOrIImmed() && !intrin.op3->isContainedIntOrIImmed());
+
+ emitAttr scalarSize = emitActualTypeSize(node->GetSimdBaseType());
+
+ // Combine the two immediates into op2Reg.
+ // Reduce scale to have a lower bound of 0.
+ GetEmitter()->emitIns_R_R_I(INS_sub, scalarSize, op2Reg, op2Reg, 1);
+ // Shift pattern left to be out of range of scale.
+ GetEmitter()->emitIns_R_R_I(INS_lsl, scalarSize, op3Reg, op3Reg, 4);
+ // Combine the two values by ORing.
+ GetEmitter()->emitIns_R_R_R(INS_orr, scalarSize, op2Reg, op2Reg, op3Reg);
+
+ // Generate the table using the combined immediate.
+ HWIntrinsicImmOpHelper helper(this, op2Reg, 0, 511, node);
+ for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd())
+ {
+ // Extract scale and pattern from the immediate
+ const int value = helper.ImmValue();
+ const int scale = (value & 0xF) + 1;
+ const insSvePattern pattern = (insSvePattern)(value >> 4);
+ GetEmitter()->emitIns_R_PATTERN_I(ins, emitSize, targetReg, pattern, scale, opt);
+ }
+
+ // Restore the original values in op2Reg and op3Reg.
+ GetEmitter()->emitIns_R_R_I(INS_and, scalarSize, op2Reg, op2Reg, 0xF);
+ GetEmitter()->emitIns_R_R_I(INS_lsr, scalarSize, op3Reg, op3Reg, 4);
+ GetEmitter()->emitIns_R_R_I(INS_add, scalarSize, op2Reg, op2Reg, 1);
+ }
+ break;
+ }
+
+ case NI_Sve_SaturatingDecrementByActiveElementCount:
+ case NI_Sve_SaturatingIncrementByActiveElementCount:
+ {
+ // RMW semantics
+ if (targetReg != op1Reg)
+ {
+ assert(targetReg != op2Reg);
+ GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true);
+ }
+
+ // Switch instruction if arg1 is unsigned.
+ if (varTypeIsUnsigned(node->GetAuxiliaryType()))
+ {
+ ins =
+ (intrin.id == NI_Sve_SaturatingDecrementByActiveElementCount) ? INS_sve_uqdecp : INS_sve_uqincp;
+ }
+
+ // If this is the scalar variant, get the correct size.
+ if (!varTypeIsSIMD(node->gtType))
+ {
+ emitSize = emitActualTypeSize(intrin.op1);
+ }
+
+ GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op2Reg, opt);
+ break;
+ }
+ case NI_Sve_Compute8BitAddresses:
+ case NI_Sve_Compute16BitAddresses:
+ case NI_Sve_Compute32BitAddresses:
+ case NI_Sve_Compute64BitAddresses:
+ {
+ static_assert_no_msg(AreContiguous(NI_Sve_Compute8BitAddresses, NI_Sve_Compute16BitAddresses,
+ NI_Sve_Compute32BitAddresses, NI_Sve_Compute64BitAddresses));
+
+ GetEmitter()->emitInsSve_R_R_R_I(ins, EA_SCALABLE, targetReg, op1Reg, op2Reg,
+ (intrin.id - NI_Sve_Compute8BitAddresses), opt,
+ INS_SCALABLE_OPTS_LSL_N);
+ break;
+ }
default:
unreached();
}
diff --git a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp
index 8ef9517c344d5..4aabaeda47cdd 100644
--- a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp
+++ b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp
@@ -180,6 +180,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
CORINFO_InstructionSet isa = HWIntrinsicInfo::lookupIsa(intrinsicId);
HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicId);
size_t numArgs = node->GetOperandCount();
+ GenTree* embMaskNode = nullptr;
GenTree* embMaskOp = nullptr;
// We need to validate that other phases of the compiler haven't introduced unsupported intrinsics
@@ -233,6 +234,9 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
op2->ClearContained();
op2->SetRegNum(targetReg);
+ // Track the original mask node so we can call genProduceReg
+ embMaskNode = node;
+
// Fixup all the already initialized variables
node = op2->AsHWIntrinsic();
intrinsicId = node->GetHWIntrinsicId();
@@ -696,13 +700,27 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
// Handle an extra operand we need to consume so that
// embedded masking can work without making the overall
// logic significantly more complex.
+
+ assert(embMaskNode != nullptr);
genConsumeReg(embMaskOp);
}
genProduceReg(node);
+
+ if (embMaskNode != nullptr)
+ {
+ // Similarly to the mask operand, we need to handle the
+ // mask node to ensure everything works correctly, particularly
+ // lifetimes and spilling if required. Doing it this way avoids
+ // needing to duplicate all our existing handling.
+
+ assert(embMaskOp != nullptr);
+ genProduceReg(embMaskNode);
+ }
return;
}
+ assert(embMaskNode == nullptr);
assert(embMaskOp == nullptr);
switch (isa)
@@ -3053,8 +3071,6 @@ void CodeGen::genFMAIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions)
regNumber targetReg = node->GetRegNum();
- genConsumeMultiOpOperands(node);
-
regNumber op1NodeReg = op1->GetRegNum();
regNumber op2NodeReg = op2->GetRegNum();
regNumber op3NodeReg = op3->GetRegNum();
@@ -3143,6 +3159,21 @@ void CodeGen::genFMAIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions)
}
}
+#ifdef DEBUG
+ // Use nums are assigned in LIR order but this node is special and doesn't
+ // actually use operands. Fix up the use nums here to avoid asserts.
+ unsigned useNum1 = op1->gtUseNum;
+ unsigned useNum2 = op2->gtUseNum;
+ unsigned useNum3 = op3->gtUseNum;
+ emitOp1->gtUseNum = useNum1;
+ emitOp2->gtUseNum = useNum2;
+ emitOp3->gtUseNum = useNum3;
+#endif
+
+ genConsumeRegs(emitOp1);
+ genConsumeRegs(emitOp2);
+ genConsumeRegs(emitOp3);
+
assert(ins != INS_invalid);
genHWIntrinsic_R_R_R_RM(ins, attr, targetReg, emitOp1->GetRegNum(), emitOp2->GetRegNum(), emitOp3, instOptions);
genProduceReg(node);
diff --git a/src/coreclr/jit/hwintrinsiclistarm64.h b/src/coreclr/jit/hwintrinsiclistarm64.h
index a207ac5bc6040..d3c880f38e0fd 100644
--- a/src/coreclr/jit/hwintrinsiclistarm64.h
+++ b/src/coreclr/jit/hwintrinsiclistarm64.h
@@ -16,23 +16,7 @@
// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
// Vector64 Intrinsics
HARDWARE_INTRINSIC(Vector64, Abs, 8, 1, false, {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, Add, 8, 2, false, {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, AndNot, 8, 2, false, {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, As, 8, 1, false, {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, AsByte, 8, 1, false, {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, AsDouble, 8, 1, false, {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, AsInt16, 8, 1, false, {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, AsInt32, 8, 1, false, {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, AsInt64, 8, 1, false, {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, AsNInt, 8, 1, false, {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, AsNUInt, 8, 1, false, {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, AsSByte, 8, 1, false, {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, AsSingle, 8, 1, false, {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, AsUInt16, 8, 1, false, {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, AsUInt32, 8, 1, false, {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, AsUInt64, 8, 1, false, {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, BitwiseAnd, 8, 2, false, {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, BitwiseOr, 8, 2, false, {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, Ceiling, 8, 1, false, {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, ConditionalSelect, 8, 3, false, {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, ConvertToDouble, 8, 1, false, {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)
@@ -49,10 +33,8 @@ HARDWARE_INTRINSIC(Vector64, Create,
HARDWARE_INTRINSIC(Vector64, CreateScalar, 8, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector64, CreateScalarUnsafe, 8, 1, true, {INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_invalid, INS_invalid, INS_fmov, INS_invalid}, HW_Category_SIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_SupportsContainment)
HARDWARE_INTRINSIC(Vector64, CreateSequence, 8, 2, false, {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, Divide, 8, 2, false, {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, Dot, 8, 2, false, {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, false, {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, EqualsAll, 8, 2, false, {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, EqualsAny, 8, 2, false, {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, false, {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, Floor, 8, 1, false, {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)
@@ -60,7 +42,6 @@ HARDWARE_INTRINSIC(Vector64, FusedMultiplyAdd,
HARDWARE_INTRINSIC(Vector64, get_AllBitsSet, 8, 0, false, {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, get_Indices, 8, 0, false, {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, get_One, 8, 0, false, {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, get_Zero, 8, 0, false, {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, true, {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)
HARDWARE_INTRINSIC(Vector64, GreaterThan, 8, 2, false, {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, GreaterThanAll, 8, 2, false, {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)
@@ -74,17 +55,13 @@ HARDWARE_INTRINSIC(Vector64, LessThanAny,
HARDWARE_INTRINSIC(Vector64, LessThanOrEqual, 8, 2, false, {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, LessThanOrEqualAll, 8, 2, false, {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, LessThanOrEqualAny, 8, 2, false, {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, Load, 8, 1, false, {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, LoadAligned, 8, 1, false, {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, LoadAlignedNonTemporal, 8, 1, false, {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, LoadUnsafe, 8, -1, false, {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, Max, 8, 2, false, {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, Min, 8, 2, false, {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, Multiply, 8, 2, false, {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, MultiplyAddEstimate, 8, 3, false, {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, Narrow, 8, 2, false, {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, Negate, 8, 1, false, {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, OnesComplement, 8, 1, false, {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, op_Addition, 8, 2, false, {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, op_BitwiseAnd, 8, 2, false, {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_Commutative)
HARDWARE_INTRINSIC(Vector64, op_BitwiseOr, 8, 2, false, {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_Commutative)
@@ -98,18 +75,12 @@ HARDWARE_INTRINSIC(Vector64, op_OnesComplement,
HARDWARE_INTRINSIC(Vector64, op_RightShift, 8, 2, false, {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, op_Subtraction, 8, 2, false, {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, op_UnaryNegation, 8, 1, false, {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, op_UnaryPlus, 8, 1, false, {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, op_UnsignedRightShift, 8, 2, false, {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, ShiftLeft, 8, 2, false, {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, ShiftRightArithmetic, 8, 2, false, {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, ShiftRightLogical, 8, 2, false, {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, Shuffle, 8, -1, false, {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, Shuffle, 8, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Vector64, Sqrt, 8, 1, false, {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, Store, 8, 2, false, {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, StoreAligned, 8, 2, false, {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, StoreAlignedNonTemporal, 8, 2, false, {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, StoreUnsafe, 8, -1, false, {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, Subtract, 8, 2, false, {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, Sum, 8, 1, false, {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, ToScalar, 8, 1, true, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_SIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SIMDScalar|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Vector64, ToVector128, 8, 1, true, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SIMD, HW_Flag_SpecialCodeGen)
@@ -117,7 +88,6 @@ HARDWARE_INTRINSIC(Vector64, ToVector128Unsafe,
HARDWARE_INTRINSIC(Vector64, WidenLower, 8, 1, false, {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, WidenUpper, 8, 1, false, {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, WithElement, 8, 3, false, {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)
-HARDWARE_INTRINSIC(Vector64, Xor, 8, 2, false, {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)
// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
// ISA Function name SIMD size NumArg EncodesExtraTypeArg Instructions Category Flags
@@ -126,28 +96,11 @@ HARDWARE_INTRINSIC(Vector64, Xor,
// Vector128 Intrinsics
HARDWARE_INTRINSIC(Vector128, Abs, 16, 1, false, {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, Add, 16, 2, false, {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, AndNot, 16, 2, false, {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, As, 16, 1, false, {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, AsByte, 16, 1, false, {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, AsDouble, 16, 1, false, {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, AsInt16, 16, 1, false, {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, AsInt32, 16, 1, false, {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, AsInt64, 16, 1, false, {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, AsNInt, 16, 1, false, {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, AsNUInt, 16, 1, false, {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, AsSByte, 16, 1, false, {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, AsSingle, 16, 1, false, {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, AsUInt16, 16, 1, false, {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, AsUInt32, 16, 1, false, {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, AsUInt64, 16, 1, false, {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, AsVector, 16, 1, false, {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, AsVector2, 16, 1, false, {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, AsVector3, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_mov, INS_invalid}, HW_Category_SIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport)
-HARDWARE_INTRINSIC(Vector128, AsVector4, 16, 1, false, {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, AsVector128, -1, 1, false, {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, BitwiseAnd, 16, 2, false, {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, BitwiseOr, 16, 2, false, {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, Ceiling, 16, 1, false, {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, ConditionalSelect, 16, 3, false, {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, ConvertToDouble, 16, 1, false, {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)
@@ -164,10 +117,8 @@ HARDWARE_INTRINSIC(Vector128, Create,
HARDWARE_INTRINSIC(Vector128, CreateScalar, 16, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, CreateScalarUnsafe, 16, 1, true, {INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_fmov, INS_fmov}, HW_Category_SIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_SupportsContainment)
HARDWARE_INTRINSIC(Vector128, CreateSequence, 16, 2, false, {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, Divide, 16, 2, false, {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, Dot, 16, 2, false, {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, false, {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, EqualsAll, 16, 2, false, {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, EqualsAny, 16, 2, false, {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, false, {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, Floor, 16, 1, false, {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)
@@ -175,7 +126,6 @@ HARDWARE_INTRINSIC(Vector128, FusedMultiplyAdd,
HARDWARE_INTRINSIC(Vector128, get_AllBitsSet, 16, 0, false, {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, get_Indices, 16, 0, false, {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, get_One, 16, 0, false, {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, get_Zero, 16, 0, false, {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, true, {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)
HARDWARE_INTRINSIC(Vector128, GetLower, 16, 1, true, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Vector128, GetUpper, 16, 1, true, {INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext}, HW_Category_SIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen)
@@ -191,17 +141,13 @@ HARDWARE_INTRINSIC(Vector128, LessThanAny,
HARDWARE_INTRINSIC(Vector128, LessThanOrEqual, 16, 2, false, {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, LessThanOrEqualAll, 16, 2, false, {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, LessThanOrEqualAny, 16, 2, false, {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, Load, 16, 1, false, {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, LoadAligned, 16, 1, false, {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, LoadAlignedNonTemporal, 16, 1, false, {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, LoadUnsafe, 16, -1, false, {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, Max, 16, 2, false, {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, Min, 16, 2, false, {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, Multiply, 16, 2, false, {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, MultiplyAddEstimate, 16, 3, false, {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, Narrow, 16, 2, false, {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, Negate, 16, 1, false, {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, OnesComplement, 16, 1, false, {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, op_Addition, 16, 2, false, {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, op_BitwiseAnd, 16, 2, false, {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_Commutative)
HARDWARE_INTRINSIC(Vector128, op_BitwiseOr, 16, 2, false, {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_Commutative)
@@ -216,17 +162,11 @@ HARDWARE_INTRINSIC(Vector128, op_Multiply,
HARDWARE_INTRINSIC(Vector128, op_OnesComplement, 16, 1, false, {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, op_Subtraction, 16, 2, false, {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, op_UnaryNegation, 16, 1, false, {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, op_UnaryPlus, 16, 1, false, {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, ShiftLeft, 16, 2, false, {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, ShiftRightArithmetic, 16, 2, false, {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, ShiftRightLogical, 16, 2, false, {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, Shuffle, 16, -1, false, {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, Shuffle, 16, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Vector128, Sqrt, 16, 1, false, {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, Store, 16, 2, false, {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, StoreAligned, 16, 2, false, {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, StoreAlignedNonTemporal, 16, 2, false, {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, StoreUnsafe, 16, -1, false, {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, Subtract, 16, 2, false, {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, Sum, 16, 1, false, {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, ToScalar, 16, 1, true, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_SIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SIMDScalar|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Vector128, WidenLower, 16, 1, false, {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)
@@ -234,7 +174,6 @@ HARDWARE_INTRINSIC(Vector128, WidenUpper,
HARDWARE_INTRINSIC(Vector128, WithElement, 16, 3, false, {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)
HARDWARE_INTRINSIC(Vector128, WithLower, 16, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, WithUpper, 16, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, Xor, 16, 2, false, {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)
// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
// ISA Function name SIMD size NumArg EncodesExtraTypeArg Instructions Category Flags
diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h
index ad264a6a03867..e047fc64447c1 100644
--- a/src/coreclr/jit/hwintrinsiclistarm64sve.h
+++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h
@@ -26,6 +26,11 @@ HARDWARE_INTRINSIC(Sve, And,
HARDWARE_INTRINSIC(Sve, AndAcross, -1, -1, false, {INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, BitwiseClear, -1, -1, false, {INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, BooleanNot, -1, -1, false, {INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation)
+HARDWARE_INTRINSIC(Sve, Compact, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_compact, INS_sve_compact, INS_sve_compact, INS_sve_compact, INS_sve_compact, INS_sve_compact}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation)
+HARDWARE_INTRINSIC(Sve, Compute8BitAddresses, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adr, INS_invalid, INS_sve_adr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
+HARDWARE_INTRINSIC(Sve, Compute16BitAddresses, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adr, INS_invalid, INS_sve_adr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
+HARDWARE_INTRINSIC(Sve, Compute32BitAddresses, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adr, INS_invalid, INS_sve_adr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
+HARDWARE_INTRINSIC(Sve, Compute64BitAddresses, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adr, INS_invalid, INS_sve_adr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Sve, ConditionalSelect, -1, 3, true, {INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_SupportsContainment)
HARDWARE_INTRINSIC(Sve, Count16BitElements, 0, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_cnth, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_NoFloatingPointUsed)
HARDWARE_INTRINSIC(Sve, Count32BitElements, 0, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_cntw, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_NoFloatingPointUsed)
@@ -68,33 +73,61 @@ HARDWARE_INTRINSIC(Sve, FusedMultiplyAddNegated,
HARDWARE_INTRINSIC(Sve, FusedMultiplySubtract, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmls, INS_sve_fmls}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation|HW_Flag_FmaIntrinsic|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Sve, FusedMultiplySubtractBySelectedScalar, -1, 4, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmls, INS_sve_fmls}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics|HW_Flag_FmaIntrinsic|HW_Flag_LowVectorOperation)
HARDWARE_INTRINSIC(Sve, FusedMultiplySubtractNegated, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fnmls, INS_sve_fnmls}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation|HW_Flag_FmaIntrinsic|HW_Flag_SpecialCodeGen)
+HARDWARE_INTRINSIC(Sve, GetActiveElementCount, -1, 2, true, {INS_sve_cntp, INS_sve_cntp, INS_sve_cntp, INS_sve_cntp, INS_sve_cntp, INS_sve_cntp, INS_sve_cntp, INS_sve_cntp, INS_sve_cntp, INS_sve_cntp}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_ExplicitMaskedOperation)
HARDWARE_INTRINSIC(Sve, LeadingSignCount, -1, -1, false, {INS_sve_cls, INS_invalid, INS_sve_cls, INS_invalid, INS_sve_cls, INS_invalid, INS_sve_cls, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, LeadingZeroCount, -1, -1, false, {INS_sve_clz, INS_sve_clz, INS_sve_clz, INS_sve_clz, INS_sve_clz, INS_sve_clz, INS_sve_clz, INS_sve_clz, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, LoadVector, -1, 2, true, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToInt16, -1, 1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToInt32, -1, 1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToInt64, -1, 1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToUInt16, -1, 1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToUInt32, -1, 1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToUInt64, -1, 1, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToInt16, -1, 2, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToInt32, -1, 2, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1b, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToUInt16, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToUInt32, -1, 2, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToUInt64, -1, 2, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorInt16NonFaultingSignExtendToInt32, -1, -1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorInt16NonFaultingSignExtendToInt64, -1, -1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorInt16NonFaultingSignExtendToUInt32, -1, -1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorInt16NonFaultingSignExtendToUInt64, -1, -1, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorInt16SignExtendToInt32, -1, 2, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorInt16SignExtendToInt64, -1, 2, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorInt16SignExtendToUInt32, -1, 2, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorInt16SignExtendToUInt64, -1, 2, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorInt32NonFaultingSignExtendToInt64, -1, -1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorInt32NonFaultingSignExtendToUInt64, -1, -1, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorInt32SignExtendToInt64, -1, 2, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorInt32SignExtendToUInt64, -1, 2, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToInt16, -1, -1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToInt32, -1, -1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToInt64, -1, -1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToUInt16, -1, -1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToUInt32, -1, -1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToUInt64, -1, -1, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToInt16, -1, 2, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToInt32, -1, 2, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToUInt16, -1, 2, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToUInt32, -1, 2, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToUInt64, -1, 2, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorUInt16NonFaultingZeroExtendToInt32, -1, 1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorUInt16NonFaultingZeroExtendToInt64, -1, 1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorUInt16NonFaultingZeroExtendToUInt32, -1, 1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorUInt16NonFaultingZeroExtendToUInt64, -1, 1, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorUInt16ZeroExtendToInt32, -1, 2, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorUInt16ZeroExtendToInt64, -1, 2, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorUInt16ZeroExtendToUInt32, -1, 2, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorUInt16ZeroExtendToUInt64, -1, 2, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorUInt32NonFaultingZeroExtendToInt64, -1, 1, false, {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)
+HARDWARE_INTRINSIC(Sve, LoadVectorUInt32NonFaultingZeroExtendToUInt64, -1, 1, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendToInt64, -1, 2, false, {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)
HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendToUInt64, -1, 2, false, {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)
+HARDWARE_INTRINSIC(Sve, Load2xVectorAndUnzip, -1, 2, true, {INS_sve_ld2b, INS_sve_ld2b, INS_sve_ld2h, INS_sve_ld2h, INS_sve_ld2w, INS_sve_ld2w, INS_sve_ld2d, INS_sve_ld2d, INS_sve_ld2w, INS_sve_ld2d}, 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, Load3xVectorAndUnzip, -1, 2, true, {INS_sve_ld3b, INS_sve_ld3b, INS_sve_ld3h, INS_sve_ld3h, INS_sve_ld3w, INS_sve_ld3w, INS_sve_ld3d, INS_sve_ld3d, INS_sve_ld3w, INS_sve_ld3d}, 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, Load4xVectorAndUnzip, -1, 2, true, {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, Max, -1, -1, false, {INS_sve_smax, INS_sve_umax, INS_sve_smax, INS_sve_umax, INS_sve_smax, INS_sve_umax, INS_sve_smax, INS_sve_umax, INS_sve_fmax, INS_sve_fmax}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, MaxAcross, -1, -1, false, {INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_fmaxv, INS_sve_fmaxv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, MaxNumber, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmaxnm, INS_sve_fmaxnm}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation)
@@ -112,6 +145,20 @@ HARDWARE_INTRINSIC(Sve, Negate,
HARDWARE_INTRINSIC(Sve, Or, -1, -1, false, {INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, OrAcross, -1, -1, false, {INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, PopCount, -1, -1, false, {INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation)
+HARDWARE_INTRINSIC(Sve, ReverseElement, -1, 1, true, {INS_sve_rev, INS_sve_rev, INS_sve_rev, INS_sve_rev, INS_sve_rev, INS_sve_rev, INS_sve_rev, INS_sve_rev, INS_sve_rev, INS_sve_rev}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
+HARDWARE_INTRINSIC(Sve, ReverseElement16, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_revh, INS_sve_revh, INS_sve_revh, INS_sve_revh, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation)
+HARDWARE_INTRINSIC(Sve, ReverseElement32, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_revw, INS_sve_revw, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation)
+HARDWARE_INTRINSIC(Sve, ReverseElement8, -1, -1, false, {INS_invalid, INS_invalid, INS_sve_revb, INS_sve_revb, INS_sve_revb, INS_sve_revb, INS_sve_revb, INS_sve_revb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation)
+HARDWARE_INTRINSIC(Sve, SaturatingDecrementBy16BitElementCount, -1, 3, true, {INS_invalid, INS_invalid, INS_sve_sqdech, INS_sve_uqdech, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_HasScalarInputVariant|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sve, SaturatingDecrementBy32BitElementCount, -1, 3, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqdecw, INS_sve_uqdecw, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_HasScalarInputVariant|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sve, SaturatingDecrementBy64BitElementCount, -1, 3, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqdecd, INS_sve_uqdecd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_HasScalarInputVariant|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sve, SaturatingDecrementBy8BitElementCount, 0, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqdecb, INS_sve_uqdecb, INS_sve_sqdecb, INS_sve_uqdecb, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sve, SaturatingDecrementByActiveElementCount, -1, 2, true, {INS_invalid, INS_sve_sqdecp, INS_sve_sqdecp, INS_sve_sqdecp, INS_sve_sqdecp, INS_sve_sqdecp, INS_sve_sqdecp, INS_sve_sqdecp, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_BaseTypeFromSecondArg|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sve, SaturatingIncrementBy16BitElementCount, -1, 3, true, {INS_invalid, INS_invalid, INS_sve_sqinch, INS_sve_uqinch, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_HasScalarInputVariant|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sve, SaturatingIncrementBy32BitElementCount, -1, 3, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqincw, INS_sve_uqincw, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_HasScalarInputVariant|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sve, SaturatingIncrementBy64BitElementCount, -1, 3, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqincd, INS_sve_uqincd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_HasScalarInputVariant|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sve, SaturatingIncrementBy8BitElementCount, 0, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqincb, INS_sve_uqincb, INS_sve_sqincb, INS_sve_uqincb, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sve, SaturatingIncrementByActiveElementCount, -1, 2, true, {INS_invalid, INS_sve_sqincp, INS_sve_sqincp, INS_sve_sqincp, INS_sve_sqincp, INS_sve_sqincp, INS_sve_sqincp, INS_sve_sqincp, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_BaseTypeFromSecondArg|HW_Flag_HasRMWSemantics)
HARDWARE_INTRINSIC(Sve, SignExtend16, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sxth, INS_invalid, INS_sve_sxth, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, SignExtend32, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sxtw, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, SignExtend8, -1, -1, false, {INS_invalid, INS_invalid, INS_sve_sxtb, INS_invalid, INS_sve_sxtb, INS_invalid, INS_sve_sxtb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation)
@@ -119,8 +166,11 @@ HARDWARE_INTRINSIC(Sve, SignExtendWideningLower,
HARDWARE_INTRINSIC(Sve, SignExtendWideningUpper, -1, 1, true, {INS_sve_sunpkhi, INS_invalid, INS_sve_sunpkhi, INS_invalid, INS_sve_sunpkhi, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg)
HARDWARE_INTRINSIC(Sve, StoreAndZip, -1, 3, true, {INS_sve_st1b, INS_sve_st1b, INS_sve_st1h, INS_sve_st1h, 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_ExplicitMaskedOperation|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, StoreNarrowing, -1, 3, true, {INS_sve_st1b, INS_sve_st1b, INS_sve_st1h, INS_sve_st1h, INS_sve_st1w, INS_sve_st1w, INS_sve_st1d, INS_sve_st1d, INS_invalid, INS_invalid}, HW_Category_MemoryStore, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_ExplicitMaskedOperation|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_LowMaskedOperation)
+HARDWARE_INTRINSIC(Sve, StoreNonTemporal, -1, 3, true, {INS_sve_stnt1b, INS_sve_stnt1b, INS_sve_stnt1h, INS_sve_stnt1h, INS_sve_stnt1w, INS_sve_stnt1w, INS_sve_stnt1d, INS_sve_stnt1d, INS_sve_stnt1w, INS_sve_stnt1d}, HW_Category_MemoryStore, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_ExplicitMaskedOperation|HW_Flag_SpecialCodeGen|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, Subtract, -1, 2, true, {INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_fsub, INS_sve_fsub}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, SubtractSaturate, -1, 2, true, {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_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation)
+HARDWARE_INTRINSIC(Sve, TransposeEven, -1, 2, true, {INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
+HARDWARE_INTRINSIC(Sve, TransposeOdd, -1, 2, true, {INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Sve, UnzipEven, -1, 2, true, {INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Sve, UnzipOdd, -1, 2, true, {INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Sve, Xor, -1, -1, false, {INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation)
@@ -147,6 +197,14 @@ HARDWARE_INTRINSIC(Sve, StoreAndZipx2,
HARDWARE_INTRINSIC(Sve, StoreAndZipx3, -1, 3, true, {INS_sve_st3b, INS_sve_st3b, INS_sve_st3h, INS_sve_st3h, INS_sve_st3w, INS_sve_st3w, INS_sve_st3d, INS_sve_st3d, INS_sve_st3w, INS_sve_st3d}, HW_Category_MemoryStore, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_NeedsConsecutiveRegisters)
HARDWARE_INTRINSIC(Sve, StoreAndZipx4, -1, 3, true, {INS_sve_st4b, INS_sve_st4b, INS_sve_st4h, INS_sve_st4h, INS_sve_st4w, INS_sve_st4w, INS_sve_st4d, INS_sve_st4d, INS_sve_st4w, INS_sve_st4d}, HW_Category_MemoryStore, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_NeedsConsecutiveRegisters)
+// Scalar variants of Saturating*By*BitElementCount. There is 8bit versions as the generic version is scalar only.
+HARDWARE_INTRINSIC(Sve, SaturatingDecrementBy16BitElementCountScalar, 0, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqdech, INS_sve_uqdech, INS_sve_sqdech, INS_sve_uqdech, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sve, SaturatingDecrementBy32BitElementCountScalar, 0, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqdecw, INS_sve_uqdecw, INS_sve_sqdecw, INS_sve_uqdecw, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sve, SaturatingDecrementBy64BitElementCountScalar, 0, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqdecd, INS_sve_uqdecd, INS_sve_sqdecd, INS_sve_uqdecd, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sve, SaturatingIncrementBy16BitElementCountScalar, 0, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqinch, INS_sve_uqinch, INS_sve_sqinch, INS_sve_uqinch, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sve, SaturatingIncrementBy32BitElementCountScalar, 0, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqincw, INS_sve_uqincw, INS_sve_sqincw, INS_sve_uqincw, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sve, SaturatingIncrementBy64BitElementCountScalar, 0, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqincd, INS_sve_uqincd, INS_sve_sqincd, INS_sve_uqincd, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics)
+
#endif // FEATURE_HW_INTRINSIC
diff --git a/src/coreclr/jit/hwintrinsiclistxarch.h b/src/coreclr/jit/hwintrinsiclistxarch.h
index aed1d0b1dfb11..578e50f76821c 100644
--- a/src/coreclr/jit/hwintrinsiclistxarch.h
+++ b/src/coreclr/jit/hwintrinsiclistxarch.h
@@ -30,28 +30,11 @@
// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
// Vector128 Intrinsics
HARDWARE_INTRINSIC(Vector128, Abs, 16, 1, false, {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, Add, 16, 2, false, {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, AndNot, 16, 2, false, {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, As, 16, 1, false, {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, AsByte, 16, 1, false, {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, AsDouble, 16, 1, false, {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, AsInt16, 16, 1, false, {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, AsInt32, 16, 1, false, {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, AsInt64, 16, 1, false, {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, AsNInt, 16, 1, false, {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, AsNUInt, 16, 1, false, {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, AsSByte, 16, 1, false, {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, AsSingle, 16, 1, false, {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, AsUInt16, 16, 1, false, {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, AsUInt32, 16, 1, false, {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, AsUInt64, 16, 1, false, {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, AsVector, 16, 1, false, {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, AsVector2, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movsd_simd, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Vector128, AsVector3, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movups, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen)
-HARDWARE_INTRINSIC(Vector128, AsVector4, 16, 1, false, {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, AsVector128, -1, 1, false, {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, BitwiseAnd, 16, 2, false, {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, BitwiseOr, 16, 2, false, {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, Ceiling, 16, 1, false, {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, ConditionalSelect, 16, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, ConvertToDouble, 16, 1, false, {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)
@@ -68,10 +51,8 @@ HARDWARE_INTRINSIC(Vector128, Create,
HARDWARE_INTRINSIC(Vector128, CreateScalar, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, CreateScalarUnsafe, 16, 1, true, {INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movss, INS_movsd_simd}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(Vector128, CreateSequence, 16, 2, false, {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, Divide, 16, 2, false, {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, Dot, 16, 2, false, {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, false, {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, EqualsAll, 16, 2, false, {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, EqualsAny, 16, 2, false, {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, false, {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, Floor, 16, 1, false, {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)
@@ -79,7 +60,6 @@ HARDWARE_INTRINSIC(Vector128, FusedMultiplyAdd,
HARDWARE_INTRINSIC(Vector128, get_AllBitsSet, 16, 0, false, {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, get_Indices, 16, 0, false, {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, get_One, 16, 0, false, {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, get_Zero, 16, 0, false, {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, false, {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)
HARDWARE_INTRINSIC(Vector128, GreaterThan, 16, 2, false, {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, GreaterThanAll, 16, 2, false, {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)
@@ -93,17 +73,13 @@ HARDWARE_INTRINSIC(Vector128, LessThanAny,
HARDWARE_INTRINSIC(Vector128, LessThanOrEqual, 16, 2, false, {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, LessThanOrEqualAll, 16, 2, false, {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, LessThanOrEqualAny, 16, 2, false, {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, Load, 16, 1, false, {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, LoadAligned, 16, 1, false, {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, LoadAlignedNonTemporal, 16, 1, false, {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, LoadUnsafe, 16, -1, false, {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, Max, 16, 2, false, {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, Min, 16, 2, false, {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, Multiply, 16, 2, false, {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, MultiplyAddEstimate, 16, 3, false, {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, Narrow, 16, 2, false, {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, Negate, 16, 1, false, {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, OnesComplement, 16, 1, false, {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, op_Addition, 16, 2, false, {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, op_BitwiseAnd, 16, 2, false, {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, op_BitwiseOr, 16, 2, false, {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)
@@ -117,18 +93,12 @@ HARDWARE_INTRINSIC(Vector128, op_OnesComplement,
HARDWARE_INTRINSIC(Vector128, op_RightShift, 16, 2, false, {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, op_Subtraction, 16, 2, false, {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, op_UnaryNegation, 16, 1, false, {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, op_UnaryPlus, 16, 1, false, {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, op_UnsignedRightShift, 16, 2, false, {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, ShiftLeft, 16, 2, false, {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, ShiftRightArithmetic, 16, 2, false, {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, ShiftRightLogical, 16, 2, false, {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, Shuffle, 16, -1, false, {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, Shuffle, 16, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Vector128, Sqrt, 16, 1, false, {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, Store, 16, 2, false, {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, StoreAligned, 16, 2, false, {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, StoreAlignedNonTemporal, 16, 2, false, {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, StoreUnsafe, 16, -1, false, {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, Subtract, 16, 2, false, {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, Sum, 16, 1, false, {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, ToScalar, 16, 1, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movss, INS_movsd_simd}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(Vector128, ToVector256, 16, 1, true, {INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movups, INS_movupd}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics)
@@ -137,7 +107,6 @@ HARDWARE_INTRINSIC(Vector128, ToVector512,
HARDWARE_INTRINSIC(Vector128, WidenLower, 16, 1, false, {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, WidenUpper, 16, 1, false, {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, WithElement, 16, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg)
-HARDWARE_INTRINSIC(Vector128, Xor, 16, 2, false, {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)
// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
// ISA Function name SIMD size NumArg EncodesExtraTypeArg Instructions Category Flags
@@ -145,25 +114,9 @@ HARDWARE_INTRINSIC(Vector128, Xor,
// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
// Vector256 Intrinsics
HARDWARE_INTRINSIC(Vector256, Abs, 32, 1, false, {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, Add, 32, 2, false, {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, AndNot, 32, 2, false, {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, As, 32, 1, false, {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|HW_Flag_AvxOnlyCompatible)
-HARDWARE_INTRINSIC(Vector256, AsByte, 32, 1, false, {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|HW_Flag_AvxOnlyCompatible)
-HARDWARE_INTRINSIC(Vector256, AsDouble, 32, 1, false, {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|HW_Flag_AvxOnlyCompatible)
-HARDWARE_INTRINSIC(Vector256, AsInt16, 32, 1, false, {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|HW_Flag_AvxOnlyCompatible)
-HARDWARE_INTRINSIC(Vector256, AsInt32, 32, 1, false, {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|HW_Flag_AvxOnlyCompatible)
-HARDWARE_INTRINSIC(Vector256, AsInt64, 32, 1, false, {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|HW_Flag_AvxOnlyCompatible)
-HARDWARE_INTRINSIC(Vector256, AsNInt, 32, 1, false, {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|HW_Flag_AvxOnlyCompatible)
-HARDWARE_INTRINSIC(Vector256, AsNUInt, 32, 1, false, {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|HW_Flag_AvxOnlyCompatible)
-HARDWARE_INTRINSIC(Vector256, AsSByte, 32, 1, false, {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|HW_Flag_AvxOnlyCompatible)
-HARDWARE_INTRINSIC(Vector256, AsSingle, 32, 1, false, {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|HW_Flag_AvxOnlyCompatible)
-HARDWARE_INTRINSIC(Vector256, AsUInt16, 32, 1, false, {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|HW_Flag_AvxOnlyCompatible)
-HARDWARE_INTRINSIC(Vector256, AsUInt32, 32, 1, false, {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|HW_Flag_AvxOnlyCompatible)
-HARDWARE_INTRINSIC(Vector256, AsUInt64, 32, 1, false, {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|HW_Flag_AvxOnlyCompatible)
HARDWARE_INTRINSIC(Vector256, AsVector, 32, 1, false, {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|HW_Flag_AvxOnlyCompatible)
HARDWARE_INTRINSIC(Vector256, AsVector256, 32, 1, false, {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|HW_Flag_AvxOnlyCompatible)
-HARDWARE_INTRINSIC(Vector256, BitwiseAnd, 32, 2, false, {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, BitwiseOr, 32, 2, false, {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, Ceiling, 32, 1, false, {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, ConditionalSelect, 32, 3, false, {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_AvxOnlyCompatible)
HARDWARE_INTRINSIC(Vector256, ConvertToDouble, 32, 1, false, {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)
@@ -180,10 +133,8 @@ HARDWARE_INTRINSIC(Vector256, Create,
HARDWARE_INTRINSIC(Vector256, CreateScalar, 32, -1, false, {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_AvxOnlyCompatible)
HARDWARE_INTRINSIC(Vector256, CreateScalarUnsafe, 32, 1, true, {INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movss, INS_movsd_simd}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_AvxOnlyCompatible)
HARDWARE_INTRINSIC(Vector256, CreateSequence, 32, 2, false, {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, Divide, 32, 2, false, {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, Dot, 32, 2, false, {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, false, {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, EqualsAll, 32, 2, false, {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, EqualsAny, 32, 2, false, {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, false, {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, Floor, 32, 1, false, {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)
@@ -191,7 +142,6 @@ HARDWARE_INTRINSIC(Vector256, FusedMultiplyAdd,
HARDWARE_INTRINSIC(Vector256, get_AllBitsSet, 32, 0, false, {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, get_Indices, 32, 0, false, {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, get_One, 32, 0, false, {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, get_Zero, 32, 0, false, {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, GetElement, 32, 2, false, {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)
HARDWARE_INTRINSIC(Vector256, GetLower, 32, 1, true, {INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movups, INS_movupd}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_AvxOnlyCompatible)
HARDWARE_INTRINSIC(Vector256, GetUpper, 32, 1, false, {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_AvxOnlyCompatible)
@@ -207,17 +157,13 @@ HARDWARE_INTRINSIC(Vector256, LessThanAny,
HARDWARE_INTRINSIC(Vector256, LessThanOrEqual, 32, 2, false, {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, LessThanOrEqualAny, 32, 2, false, {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, LessThanOrEqualAll, 32, 2, false, {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, Load, 32, 1, false, {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, LoadAligned, 32, 1, false, {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, LoadAlignedNonTemporal, 32, 1, false, {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, LoadUnsafe, 32, -1, false, {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, Max, 32, 2, false, {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, Min, 32, 2, false, {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, Multiply, 32, 2, false, {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, MultiplyAddEstimate, 32, 3, false, {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, Narrow, 32, 2, false, {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, Negate, 32, 1, false, {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, OnesComplement, 32, 1, false, {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, op_Addition, 32, 2, false, {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, op_BitwiseAnd, 32, 2, false, {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, op_BitwiseOr, 32, 2, false, {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)
@@ -231,18 +177,12 @@ HARDWARE_INTRINSIC(Vector256, op_OnesComplement,
HARDWARE_INTRINSIC(Vector256, op_RightShift, 32, 2, false, {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, op_Subtraction, 32, 2, false, {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, op_UnaryNegation, 32, 1, false, {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, op_UnaryPlus, 32, 1, false, {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, op_UnsignedRightShift, 32, 2, false, {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, ShiftLeft, 32, 2, false, {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, ShiftRightArithmetic, 32, 2, false, {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, ShiftRightLogical, 32, 2, false, {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, Shuffle, 32, -1, false, {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, Shuffle, 32, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Vector256, Sqrt, 32, 1, false, {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, Store, 32, 2, false, {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|HW_Flag_AvxOnlyCompatible)
HARDWARE_INTRINSIC(Vector256, StoreAligned, 32, 2, false, {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|HW_Flag_AvxOnlyCompatible)
HARDWARE_INTRINSIC(Vector256, StoreAlignedNonTemporal, 32, 2, false, {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|HW_Flag_AvxOnlyCompatible)
HARDWARE_INTRINSIC(Vector256, StoreUnsafe, 32, -1, false, {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|HW_Flag_AvxOnlyCompatible)
-HARDWARE_INTRINSIC(Vector256, Subtract, 32, 2, false, {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, Sum, 32, 1, false, {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, ToScalar, 32, 1, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movss, INS_movsd_simd}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_AvxOnlyCompatible)
HARDWARE_INTRINSIC(Vector256, ToVector512, 32, 1, true, {INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_vmovdqu64, INS_vmovdqu64, INS_movups, INS_movupd}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg)
@@ -252,7 +192,6 @@ HARDWARE_INTRINSIC(Vector256, WidenUpper,
HARDWARE_INTRINSIC(Vector256, WithElement, 32, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_AvxOnlyCompatible)
HARDWARE_INTRINSIC(Vector256, WithLower, 32, 2, false, {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_AvxOnlyCompatible)
HARDWARE_INTRINSIC(Vector256, WithUpper, 32, 2, false, {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_AvxOnlyCompatible)
-HARDWARE_INTRINSIC(Vector256, Xor, 32, 2, false, {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)
// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
// ISA Function name SIMD size NumArg EncodesExtraTypeArg Instructions Category Flags
@@ -260,26 +199,10 @@ HARDWARE_INTRINSIC(Vector256, Xor,
// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
// Vector512 Intrinsics
HARDWARE_INTRINSIC(Vector512, Abs, 64, 1, false, {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(Vector512, Add, 64, 2, false, {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(Vector512, AndNot, 64, 2, false, {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(Vector512, As, 64, 1, false, {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(Vector512, AsByte, 64, 1, false, {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(Vector512, AsDouble, 64, 1, false, {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(Vector512, AsInt16, 64, 1, false, {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(Vector512, AsInt32, 64, 1, false, {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(Vector512, AsInt64, 64, 1, false, {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(Vector512, AsNInt, 64, 1, false, {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(Vector512, AsNUInt, 64, 1, false, {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(Vector512, AsSByte, 64, 1, false, {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(Vector512, AsSingle, 64, 1, false, {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(Vector512, AsUInt16, 64, 1, false, {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(Vector512, AsUInt32, 64, 1, false, {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(Vector512, AsUInt64, 64, 1, false, {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(Vector512, AsVector, 64, 1, false, {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(Vector512, AsVector512, 64, 1, false, {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(Vector512, BitwiseAnd, 64, 2, false, {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(Vector512, ConditionalSelect, 64, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector512, BitwiseOr, 64, 2, false, {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(Vector512, Ceiling, 64, 1, false, {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(Vector512, Create, 64, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector512, CreateScalar, 64, -1, false, {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)
@@ -295,9 +218,7 @@ HARDWARE_INTRINSIC(Vector512, ConvertToUInt32,
HARDWARE_INTRINSIC(Vector512, ConvertToUInt32Native, 64, 1, false, {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(Vector512, ConvertToUInt64, 64, 1, false, {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(Vector512, ConvertToUInt64Native, 64, 1, false, {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(Vector512, Divide, 64, 2, false, {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(Vector512, Equals, 64, 2, false, {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(Vector512, EqualsAll, 64, 2, false, {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(Vector512, EqualsAny, 64, 2, false, {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(Vector512, ExtractMostSignificantBits, 64, 1, false, {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(Vector512, Floor, 64, 1, false, {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)
@@ -305,7 +226,6 @@ HARDWARE_INTRINSIC(Vector512, FusedMultiplyAdd,
HARDWARE_INTRINSIC(Vector512, get_AllBitsSet, 64, 0, false, {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(Vector512, get_Indices, 64, 0, false, {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(Vector512, get_One, 64, 0, false, {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(Vector512, get_Zero, 64, 0, false, {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(Vector512, GetElement, 64, 2, false, {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)
HARDWARE_INTRINSIC(Vector512, GetLower, 64, 1, true, {INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_vmovdqu64, INS_vmovdqu64, INS_movups, INS_movupd}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Vector512, GetLower128, 64, 1, true, {INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_vmovdqu64, INS_vmovdqu64, INS_movups, INS_movupd}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg)
@@ -322,17 +242,13 @@ HARDWARE_INTRINSIC(Vector512, LessThanAny,
HARDWARE_INTRINSIC(Vector512, LessThanOrEqual, 64, 2, false, {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(Vector512, LessThanOrEqualAll, 64, 2, false, {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(Vector512, LessThanOrEqualAny, 64, 2, false, {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(Vector512, Load, 64, 1, false, {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(Vector512, LoadAligned, 64, 1, false, {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(Vector512, LoadAlignedNonTemporal, 64, 1, false, {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(Vector512, LoadUnsafe, 64, -1, false, {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(Vector512, Max, 64, 2, false, {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(Vector512, Min, 64, 2, false, {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(Vector512, Multiply, 64, 2, false, {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(Vector512, MultiplyAddEstimate, 64, 3, false, {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(Vector512, Narrow, 64, 2, false, {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(Vector512, Negate, 64, 1, false, {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(Vector512, OnesComplement, 64, 1, false, {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(Vector512, op_Addition, 64, 2, false, {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(Vector512, op_BitwiseAnd, 64, 2, false, {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(Vector512, op_BitwiseOr, 64, 2, false, {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)
@@ -346,18 +262,12 @@ HARDWARE_INTRINSIC(Vector512, op_OnesComplement,
HARDWARE_INTRINSIC(Vector512, op_RightShift, 64, 2, false, {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(Vector512, op_Subtraction, 64, 2, false, {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(Vector512, op_UnaryNegation, 64, 1, false, {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(Vector512, op_UnaryPlus, 64, 1, false, {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(Vector512, op_UnsignedRightShift, 64, 2, false, {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(Vector512, ShiftLeft, 64, 2, false, {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(Vector512, ShiftRightArithmetic, 64, 2, false, {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(Vector512, ShiftRightLogical, 64, 2, false, {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(Vector512, Shuffle, 64, -1, false, {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(Vector512, Shuffle, 64, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Vector512, Sqrt, 64, 1, false, {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(Vector512, Store, 64, 2, false, {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(Vector512, StoreAligned, 64, 2, false, {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(Vector512, StoreAlignedNonTemporal, 64, 2, false, {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(Vector512, StoreUnsafe, 64, -1, false, {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(Vector512, Subtract, 64, 2, false, {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(Vector512, Sum, 64, 1, false, {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(Vector512, ToScalar, 64, 1, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movss, INS_movsd_simd}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg)
HARDWARE_INTRINSIC(Vector512, WidenLower, 64, 1, false, {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)
@@ -365,7 +275,6 @@ HARDWARE_INTRINSIC(Vector512, WidenUpper,
HARDWARE_INTRINSIC(Vector512, WithElement, 64, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg)
HARDWARE_INTRINSIC(Vector512, WithLower, 64, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector512, WithUpper, 64, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector512, Xor, 64, 2, false, {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)
// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
// ISA Function name SIMD size NumArg EncodesExtraTypeArg Instructions Category Flags
diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp
index 8aaee01f4c41c..917c0c9d95641 100644
--- a/src/coreclr/jit/hwintrinsicxarch.cpp
+++ b/src/coreclr/jit/hwintrinsicxarch.cpp
@@ -955,6 +955,7 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdT
// clsHnd -- class handle containing the intrinsic function.
// method -- method handle of the intrinsic function.
// sig -- signature of the intrinsic call.
+// entryPoint -- The entry point information required for R2R scenarios
// simdBaseJitType -- generic argument of the intrinsic.
// retType -- return type of the intrinsic.
// mustExpand -- true if the intrinsic must return a GenTree*; otherwise, false
@@ -965,7 +966,7 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdT
GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
CORINFO_CLASS_HANDLE clsHnd,
CORINFO_METHOD_HANDLE method,
- CORINFO_SIG_INFO* sig,
+ CORINFO_SIG_INFO* sig R2RARG(CORINFO_CONST_LOOKUP* entryPoint),
CorInfoType simdBaseJitType,
var_types retType,
unsigned simdSize,
@@ -986,6 +987,13 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
assert(varTypeIsArithmetic(simdBaseType));
}
+#if defined(FEATURE_READYTORUN)
+ CORINFO_CONST_LOOKUP emptyEntryPoint;
+
+ emptyEntryPoint.addr = nullptr;
+ emptyEntryPoint.accessType = IAT_VALUE;
+#endif // FEATURE_READYTORUN
+
switch (intrinsic)
{
case NI_Vector128_Abs:
@@ -1003,9 +1011,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector128_Add:
- case NI_Vector256_Add:
- case NI_Vector512_Add:
case NI_Vector128_op_Addition:
case NI_Vector256_op_Addition:
case NI_Vector512_op_Addition:
@@ -1039,59 +1044,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector128_As:
- case NI_Vector128_AsByte:
- case NI_Vector128_AsDouble:
- case NI_Vector128_AsInt16:
- case NI_Vector128_AsInt32:
- case NI_Vector128_AsInt64:
- case NI_Vector128_AsNInt:
- case NI_Vector128_AsNUInt:
- case NI_Vector128_AsSByte:
- case NI_Vector128_AsSingle:
- case NI_Vector128_AsUInt16:
- case NI_Vector128_AsUInt32:
- case NI_Vector128_AsUInt64:
- case NI_Vector128_AsVector4:
- case NI_Vector256_As:
- case NI_Vector256_AsByte:
- case NI_Vector256_AsDouble:
- case NI_Vector256_AsInt16:
- case NI_Vector256_AsInt32:
- case NI_Vector256_AsInt64:
- case NI_Vector256_AsNInt:
- case NI_Vector256_AsNUInt:
- case NI_Vector256_AsSByte:
- case NI_Vector256_AsSingle:
- case NI_Vector256_AsUInt16:
- case NI_Vector256_AsUInt32:
- case NI_Vector256_AsUInt64:
- case NI_Vector512_As:
- case NI_Vector512_AsByte:
- case NI_Vector512_AsDouble:
- case NI_Vector512_AsInt16:
- case NI_Vector512_AsInt32:
- case NI_Vector512_AsInt64:
- case NI_Vector512_AsNInt:
- case NI_Vector512_AsNUInt:
- case NI_Vector512_AsSByte:
- case NI_Vector512_AsSingle:
- case NI_Vector512_AsUInt16:
- case NI_Vector512_AsUInt32:
- case NI_Vector512_AsUInt64:
- {
- // We fold away the cast here, as it only exists to satisfy
- // the type system. It is safe to do this here since the retNode type
- // and the signature return type are both the same TYP_SIMD.
-
- assert(sig->numArgs == 1);
-
- retNode = impSIMDPopStack();
- SetOpLclRelatedToSIMDIntrinsic(retNode);
- assert(retNode->gtType == getSIMDTypeForSize(getSIMDTypeSizeInBytes(sig->retTypeSigClass)));
- break;
- }
-
case NI_Vector128_AsVector:
{
assert(sig->numArgs == 1);
@@ -1100,8 +1052,8 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
if (vectorTByteLength == YMM_REGSIZE_BYTES)
{
// Vector