first commit

This commit is contained in:
lethanhsonvsp
2025-11-17 15:16:36 +07:00
commit a40d0921eb
17012 changed files with 2652386 additions and 0 deletions

View File

@@ -0,0 +1,239 @@
using System;
using System.Runtime.CompilerServices;
// Make internals visible for BurstGlobalCompilerOptions
[assembly: InternalsVisibleTo("Unity.Burst.CodeGen")]
[assembly: InternalsVisibleTo("Unity.Burst.Editor")]
// Make internals visible to Unity burst tests
[assembly: InternalsVisibleTo("Unity.Burst.Tests.UnitTests")]
[assembly: InternalsVisibleTo("Unity.Burst.Editor.Tests")]
[assembly: InternalsVisibleTo("Unity.Burst.Benchmarks")]
namespace Unity.Burst
{
/// <summary>
/// How the code should be optimized.
/// </summary>
public enum OptimizeFor
{
/// <summary>
/// The default optimization mode - uses <see cref="OptimizeFor.Balanced"/>.
/// </summary>
Default = 0,
/// <summary>
/// Optimize for performance - the compiler should make the most optimal binary possible.
/// </summary>
Performance = 1,
/// <summary>
/// Optimize for size - the compiler should make the smallest binary possible.
/// </summary>
Size = 2,
/// <summary>
/// Optimize for fast compilation - the compiler should perform some optimization, but take as little time as possible to do it.
/// </summary>
FastCompilation = 3,
/// <summary>
/// Optimize for balanced compilation - ensuring that good performance is obtained while keeping compile time as low as possible.
/// </summary>
Balanced = 4,
}
#if !BURST_COMPILER_SHARED
// FloatMode and FloatPrecision must be kept in sync with burst.h / Burst.Backend
/// <summary>
/// Represents the floating point optimization mode for compilation.
/// </summary>
public enum FloatMode
{
/// <summary>
/// Use the default target floating point mode - <see cref="FloatMode.Strict"/>.
/// </summary>
Default = 0,
/// <summary>
/// No floating point optimizations are performed.
/// </summary>
Strict = 1,
/// <summary>
/// Reserved for future.
/// </summary>
Deterministic = 2,
/// <summary>
/// <para>Allows algebraically equivalent optimizations (which can alter the results of calculations), it implies :</para>
/// <para>optimizations can assume results and arguments contain no NaNs or +/- Infinity and treat sign of zero as insignificant.</para>
/// <para>optimizations can use reciprocals - 1/x * y , instead of y/x.</para>
/// <para>optimizations can use fused instructions, e.g. madd.</para>
/// </summary>
Fast = 3,
}
/// <summary>
/// Represents the floating point precision used for certain builtin operations e.g. sin/cos.
/// </summary>
public enum FloatPrecision
{
/// <summary>
/// Use the default target floating point precision - <see cref="FloatPrecision.Medium"/>.
/// </summary>
Standard = 0,
/// <summary>
/// Compute with an accuracy of 1 ULP - highly accurate, but increased runtime as a result, should not be required for most purposes.
/// </summary>
High = 1,
/// <summary>
/// Compute with an accuracy of 3.5 ULP - considered acceptable accuracy for most tasks.
/// </summary>
Medium = 2,
/// <summary>
/// Compute with an accuracy lower than or equal to <see cref="FloatPrecision.Medium"/>, with some range restrictions (defined per function).
/// </summary>
Low = 3,
}
/// <summary>
/// This attribute is used to tag jobs or function-pointers as being Burst compiled, and optionally set compilation parameters.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Assembly)]
public class BurstCompileAttribute : System.Attribute
{
/// <summary>
/// Gets or sets the float mode of operation for this Burst compilation.
/// </summary>
/// <value>
/// The default is <see cref="FloatMode.Default"/>.
/// </value>
public FloatMode FloatMode { get; set; }
/// <summary>
/// Gets or sets the floating point precision to use for this Burst compilation.
/// Allows you to trade accuracy for speed of computation, useful when you don't require much precision.
/// </summary>
/// <value>
/// The default is <see cref="FloatPrecision.Standard"/>.
/// </value>
public FloatPrecision FloatPrecision { get; set; }
internal bool? _compileSynchronously;
/// <summary>
/// Gets or sets whether or not to Burst compile the code immediately on first use, or in the background over time.
/// </summary>
/// <value>The default is <c>false</c>, <c>true</c> will force this code to be compiled synchronously on first invocation.</value>
public bool CompileSynchronously
{
get => _compileSynchronously.HasValue ? _compileSynchronously.Value : false;
set => _compileSynchronously = value;
}
internal bool? _debug;
/// <summary>
/// Gets or sets whether to compile the code in a way that allows it to be debugged.
/// If this is set to <c>true</c>, the current implementation disables optimisations on this method
/// allowing it to be debugged using a Native debugger.
/// </summary>
/// <value>
/// The default is <c>false</c>.
/// </value>
public bool Debug
{
get => _debug.HasValue ? _debug.Value : false;
set => _debug = value;
}
internal bool? _disableSafetyChecks;
/// <summary>
/// Gets or sets whether to disable safety checks for the current job or function pointer.
/// If this is set to <c>true</c>, the current job or function pointer will be compiled
/// with safety checks disabled unless the global 'Safety Checks/Force On' option is active.
/// </summary>
/// <value>
/// The default is <c>false</c>.
/// </value>
public bool DisableSafetyChecks
{
get => _disableSafetyChecks.HasValue ? _disableSafetyChecks.Value : false;
set => _disableSafetyChecks = value;
}
internal bool? _disableDirectCall;
/// <summary>
/// Gets or sets a boolean to disable the translation of a static method call as direct call to
/// the generated native method. By default, when compiling static methods with Burst and calling
/// them from C#, they will be translated to a direct call to the Burst generated method.
/// code.
/// </summary>
/// <value>
/// The default is <c>false</c>.
/// </value>
public bool DisableDirectCall
{
get => _disableDirectCall.HasValue ? _disableDirectCall.Value : false;
set => _disableDirectCall = value;
}
/// <summary>
/// How should this entry-point be optimized.
/// </summary>
/// <value>
/// The default is <see cref="OptimizeFor.Default"/>.
/// </value>
public OptimizeFor OptimizeFor { get; set; }
internal string[] Options { get; set; }
/// <summary>
/// Tags a struct/method/class as being Burst compiled, with the default <see cref="FloatPrecision"/>, <see cref="FloatMode"/> and <see cref="CompileSynchronously"/>.
/// </summary>
/// <example>
/// <code>
/// [BurstCompile]
/// struct MyMethodsAreCompiledByBurstUsingTheDefaultSettings
/// {
/// //....
/// }
///</code>
/// </example>
public BurstCompileAttribute()
{
}
/// <summary>
/// Tags a struct/method/class as being Burst compiled, with the specified <see cref="FloatPrecision"/> and <see cref="FloatMode"/>.
/// </summary>
/// <example>
/// <code>
/// [BurstCompile(FloatPrecision.Low, FloatMode.Fast)]
/// struct MyMethodsAreCompiledByBurstWithLowPrecisionAndFastFloatingPointMode
/// {
/// //....
/// }
///</code>
///</example>
/// <param name="floatPrecision">Specify the required floating point precision.</param>
/// <param name="floatMode">Specify the required floating point mode.</param>
public BurstCompileAttribute(FloatPrecision floatPrecision, FloatMode floatMode)
{
FloatMode = floatMode;
FloatPrecision = floatPrecision;
}
internal BurstCompileAttribute(string[] options)
{
Options = options;
}
}
#endif
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c0bbf37c91f333828d3f05b922bc839d
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,868 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using UnityEngine.Scripting;
using System.Linq;
using System.Text;
namespace Unity.Burst
{
/// <summary>
/// The burst compiler runtime frontend.
/// </summary>
///
public static class BurstCompiler
{
/// <summary>
/// Check if the LoadAdditionalLibrary API is supported by the current version of Unity
/// </summary>
/// <returns>True if the LoadAdditionalLibrary API can be used by the current version of Unity</returns>
public static bool IsLoadAdditionalLibrarySupported()
{
return IsApiAvailable("LoadBurstLibrary");
}
#if UNITY_EDITOR
static unsafe BurstCompiler()
{
// Store pointers to Log and Compile callback methods.
// For more info about why we need to do this, see comments in CallbackStubManager.
string GetFunctionPointer<TDelegate>(TDelegate callback)
{
GCHandle.Alloc(callback); // Ensure delegate is never garbage-collected.
var callbackFunctionPointer = Marshal.GetFunctionPointerForDelegate(callback);
return "0x" + callbackFunctionPointer.ToInt64().ToString("X16");
}
EagerCompileLogCallbackFunctionPointer = GetFunctionPointer<LogCallbackDelegate>(EagerCompileLogCallback);
ManagedResolverFunctionPointer = GetFunctionPointer<ManagedFnPtrResolverDelegate>(ManagedResolverFunction);
ProgressCallbackFunctionPointer = GetFunctionPointer<ProgressCallbackDelegate>(ProgressCallback);
ProfileBeginCallbackFunctionPointer = GetFunctionPointer<ProfileBeginCallbackDelegate>(ProfileBeginCallback);
ProfileEndCallbackFunctionPointer = GetFunctionPointer<ProfileEndCallbackDelegate>(ProfileEndCallback);
}
#endif
private class CommandBuilder
{
private StringBuilder _builder;
private bool _hasArgs;
public CommandBuilder()
{
_builder = new StringBuilder();
_hasArgs = false;
}
public CommandBuilder Begin(string cmd)
{
_builder.Clear();
_hasArgs = false;
_builder.Append(cmd);
return this;
}
public CommandBuilder With(string arg)
{
if (!_hasArgs) _builder.Append(' ');
_hasArgs = true;
_builder.Append(arg);
return this;
}
public CommandBuilder With(IntPtr arg)
{
if (!_hasArgs) _builder.Append(' ');
_hasArgs = true;
_builder.AppendFormat("0x{0:X16}", arg.ToInt64());
return this;
}
public CommandBuilder And(char sep = '|')
{
_builder.Append(sep);
return this;
}
public string SendToCompiler()
{
return SendRawCommandToCompiler(_builder.ToString());
}
}
[ThreadStatic]
private static CommandBuilder _cmdBuilder;
private static CommandBuilder BeginCompilerCommand(string cmd)
{
if (_cmdBuilder == null)
{
_cmdBuilder = new CommandBuilder();
}
return _cmdBuilder.Begin(cmd);
}
#if BURST_INTERNAL
[ThreadStatic]
public static Func<object, IntPtr> InternalCompiler;
#endif
/// <summary>
/// Internal variable setup by BurstCompilerOptions.
/// </summary>
#if BURST_INTERNAL
[ThreadStatic] // As we are changing this boolean via BurstCompilerOptions in btests and we are running multithread tests
// we would change a global and it would generate random errors, so specifically for btests, we are using a TLS.
public
#else
internal
#endif
static bool _IsEnabled;
/// <summary>
/// Gets a value indicating whether Burst is enabled.
/// </summary>
#if UNITY_EDITOR || BURST_INTERNAL
public static bool IsEnabled => _IsEnabled;
#else
public static bool IsEnabled => _IsEnabled && BurstCompilerHelper.IsBurstGenerated;
#endif
/// <summary>
/// Gets the global options for the burst compiler.
/// </summary>
public static readonly BurstCompilerOptions Options = new BurstCompilerOptions(true);
/// <summary>
/// Sets the execution mode for all jobs spawned from now on.
/// </summary>
/// <param name="mode">Specifiy the required execution mode</param>
public static void SetExecutionMode(BurstExecutionEnvironment mode)
{
Burst.LowLevel.BurstCompilerService.SetCurrentExecutionMode((uint)mode);
}
/// <summary>
/// Retrieve the current execution mode that is configured.
/// </summary>
/// <returns>Currently configured execution mode</returns>
public static BurstExecutionEnvironment GetExecutionMode()
{
return (BurstExecutionEnvironment)Burst.LowLevel.BurstCompilerService.GetCurrentExecutionMode();
}
/// <summary>
/// Compile the following delegate with burst and return a new delegate.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="delegateMethod"></param>
/// <returns></returns>
/// <remarks>NOT AVAILABLE, unsafe to use</remarks>
internal static unsafe T CompileDelegate<T>(T delegateMethod) where T : class
{
// We have added support for runtime CompileDelegate in 2018.2+
void* function = Compile(delegateMethod, false);
object res = System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer((IntPtr)function, delegateMethod.GetType());
return (T)res;
}
[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
private static void VerifyDelegateIsNotMulticast<T>(T delegateMethod) where T : class
{
var delegateKind = delegateMethod as Delegate;
if (delegateKind.GetInvocationList().Length > 1)
{
throw new InvalidOperationException($"Burst does not support multicast delegates, please use a regular delegate for `{delegateMethod}'");
}
}
[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
private static void VerifyDelegateHasCorrectUnmanagedFunctionPointerAttribute<T>(T delegateMethod) where T : class
{
var attrib = delegateMethod.GetType().GetCustomAttribute<System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute>();
if (attrib == null || attrib.CallingConvention != CallingConvention.Cdecl)
{
#if !BURST_INTERNAL
UnityEngine.Debug.LogWarning($"The delegate type {delegateMethod.GetType().FullName} should be decorated with [UnmanagedFunctionPointer(CallingConvention.Cdecl)] to ensure runtime interoperabilty between managed code and Burst-compiled code.");
#endif
}
}
/// <summary>
/// DO NOT USE - deprecated.
/// </summary>
/// <param name="burstMethodHandle">The Burst method to compile.</param>
/// <param name="managedMethodHandle">The fallback managed method to use.</param>
/// <param name="delegateTypeHandle">The type of the delegate used to execute these methods.</param>
/// <returns>Nothing</returns>
[Obsolete("This method will be removed in a future version of Burst")]
public static unsafe IntPtr CompileILPPMethod(RuntimeMethodHandle burstMethodHandle, RuntimeMethodHandle managedMethodHandle, RuntimeTypeHandle delegateTypeHandle)
{
throw new NotImplementedException();
}
/// <summary>
/// Compile an IL Post-Processed method.
/// </summary>
/// <param name="burstMethodHandle">The Burst method to compile.</param>
/// <returns>A token that must be passed to <see cref="GetILPPMethodFunctionPointer2"/> to get an actual executable function pointer.</returns>
public static unsafe IntPtr CompileILPPMethod2(RuntimeMethodHandle burstMethodHandle)
{
if (burstMethodHandle.Value == IntPtr.Zero)
{
throw new ArgumentNullException(nameof(burstMethodHandle));
}
OnCompileILPPMethod2?.Invoke();
var burstMethod = (MethodInfo)MethodBase.GetMethodFromHandle(burstMethodHandle);
return (IntPtr)Compile(new FakeDelegate(burstMethod), burstMethod, isFunctionPointer: true, isILPostProcessing: true);
}
internal static Action OnCompileILPPMethod2;
/// <summary>
/// DO NOT USE - deprecated.
/// </summary>
/// <param name="ilppMethod">The result of a previous call to <see cref="CompileILPPMethod"/>.</param>
/// <returns>Nothing.</returns>
[Obsolete("This method will be removed in a future version of Burst")]
public static unsafe void* GetILPPMethodFunctionPointer(IntPtr ilppMethod)
{
throw new NotImplementedException();
}
/// <summary>
/// For a previous call to <see cref="CompileILPPMethod2"/>, get the actual executable function pointer.
/// </summary>
/// <param name="ilppMethod">The result of a previous call to <see cref="CompileILPPMethod"/>.</param>
/// <param name="managedMethodHandle">The fallback managed method to use.</param>
/// <param name="delegateTypeHandle">The type of the delegate used to execute these methods.</param>
/// <returns>A pointer into an executable region, for running the function pointer.</returns>
public static unsafe void* GetILPPMethodFunctionPointer2(IntPtr ilppMethod, RuntimeMethodHandle managedMethodHandle, RuntimeTypeHandle delegateTypeHandle)
{
if (ilppMethod == IntPtr.Zero)
{
throw new ArgumentNullException(nameof(ilppMethod));
}
if (managedMethodHandle.Value == IntPtr.Zero)
{
throw new ArgumentNullException(nameof(managedMethodHandle));
}
if (delegateTypeHandle.Value == IntPtr.Zero)
{
throw new ArgumentNullException(nameof(delegateTypeHandle));
}
// If we are in the editor, we need to route a command to the compiler to start compiling the deferred ILPP compilation.
// Otherwise if we're in Burst's internal testing, or in a player build, we already actually have the actual executable
// pointer address, and we just return that.
#if UNITY_EDITOR
var managedMethod = (MethodInfo)MethodBase.GetMethodFromHandle(managedMethodHandle);
var delegateType = Type.GetTypeFromHandle(delegateTypeHandle);
var managedFallbackDelegate = Delegate.CreateDelegate(delegateType, managedMethod);
var handle = GCHandle.Alloc(managedFallbackDelegate);
var result =
BeginCompilerCommand(BurstCompilerOptions.CompilerCommandILPPCompilation)
.With(ilppMethod).And()
.With(ManagedResolverFunctionPointer).And()
.With(GCHandle.ToIntPtr(handle))
.SendToCompiler();
return new IntPtr(Convert.ToInt64(result, 16)).ToPointer();
#else
return ilppMethod.ToPointer();
#endif
}
/// <summary>
/// DO NOT USE - deprecated.
/// </summary>
/// <param name="handle">A runtime method handle.</param>
/// <returns>Nothing.</returns>
[Obsolete("This method will be removed in a future version of Burst")]
public static unsafe void* CompileUnsafeStaticMethod(RuntimeMethodHandle handle)
{
throw new NotImplementedException();
}
/// <summary>
/// Compile the following delegate into a function pointer with burst, invokable from a Burst Job or from regular C#.
/// </summary>
/// <typeparam name="T">Type of the delegate of the function pointer</typeparam>
/// <param name="delegateMethod">The delegate to compile</param>
/// <returns>A function pointer invokable from a Burst Job or from regular C#</returns>
public static unsafe FunctionPointer<T> CompileFunctionPointer<T>(T delegateMethod) where T : class
{
VerifyDelegateIsNotMulticast<T>(delegateMethod);
VerifyDelegateHasCorrectUnmanagedFunctionPointerAttribute<T>(delegateMethod);
// We have added support for runtime CompileDelegate in 2018.2+
void* function = Compile(delegateMethod, true);
return new FunctionPointer<T>(new IntPtr(function));
}
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal class StaticTypeReinitAttribute : Attribute
{
public readonly Type reinitType;
public StaticTypeReinitAttribute(Type toReinit)
{
reinitType = toReinit;
}
}
private static unsafe void* Compile(object delegateObj, bool isFunctionPointer)
{
if (!(delegateObj is Delegate)) throw new ArgumentException("object instance must be a System.Delegate", nameof(delegateObj));
var delegateMethod = (Delegate)delegateObj;
return Compile(delegateMethod, delegateMethod.Method, isFunctionPointer, false);
}
private static unsafe void* Compile(object delegateObj, MethodInfo methodInfo, bool isFunctionPointer, bool isILPostProcessing)
{
if (delegateObj == null) throw new ArgumentNullException(nameof(delegateObj));
if (delegateObj.GetType().IsGenericType)
{
throw new InvalidOperationException($"The delegate type `{delegateObj.GetType()}` must be a non-generic type");
}
if (!methodInfo.IsStatic)
{
throw new InvalidOperationException($"The method `{methodInfo}` must be static. Instance methods are not supported");
}
if (methodInfo.IsGenericMethod)
{
throw new InvalidOperationException($"The method `{methodInfo}` must be a non-generic method");
}
#if ENABLE_IL2CPP
if (isFunctionPointer && !isILPostProcessing &&
methodInfo.GetCustomAttributes().All(s => s.GetType().Name != "MonoPInvokeCallbackAttribute"))
{
UnityEngine.Debug.Log($"The method `{methodInfo}` must have `MonoPInvokeCallback` attribute to be compatible with IL2CPP!");
}
#endif
void* function;
#if BURST_INTERNAL
// Internally in Burst tests, we callback the C# method instead
function = (void*)InternalCompiler(delegateObj);
#else
Delegate managedFallbackDelegateMethod = null;
if (!isILPostProcessing)
{
managedFallbackDelegateMethod = delegateObj as Delegate;
}
var delegateMethod = delegateObj as Delegate;
#if UNITY_EDITOR
string defaultOptions;
// In case Burst is disabled entirely from the command line
if (BurstCompilerOptions.ForceDisableBurstCompilation)
{
if (isILPostProcessing)
{
return null;
}
else
{
GCHandle.Alloc(managedFallbackDelegateMethod);
function = (void*)Marshal.GetFunctionPointerForDelegate(managedFallbackDelegateMethod);
return function;
}
}
if (isILPostProcessing)
{
defaultOptions = "--" + BurstCompilerOptions.OptionJitIsForFunctionPointer + "\n";
}
else if (isFunctionPointer)
{
defaultOptions = "--" + BurstCompilerOptions.OptionJitIsForFunctionPointer + "\n";
// Make sure that the delegate will never be collected
var delHandle = GCHandle.Alloc(managedFallbackDelegateMethod);
defaultOptions += "--" + BurstCompilerOptions.OptionJitManagedDelegateHandle + "0x" + ManagedResolverFunctionPointer + "|" + "0x" + GCHandle.ToIntPtr(delHandle).ToInt64().ToString("X16");
}
else
{
defaultOptions = "--" + BurstCompilerOptions.OptionJitEnableSynchronousCompilation;
}
string extraOptions;
// The attribute is directly on the method, so we recover the underlying method here
if (Options.TryGetOptions(methodInfo, out extraOptions, isForILPostProcessing: isILPostProcessing))
{
if (!string.IsNullOrWhiteSpace(extraOptions))
{
defaultOptions += "\n" + extraOptions;
}
var delegateMethodId = Unity.Burst.LowLevel.BurstCompilerService.CompileAsyncDelegateMethod(delegateObj, defaultOptions);
function = Unity.Burst.LowLevel.BurstCompilerService.GetAsyncCompiledAsyncDelegateMethod(delegateMethodId);
}
#else
// The attribute is directly on the method, so we recover the underlying method here
if (BurstCompilerOptions.HasBurstCompileAttribute(methodInfo))
{
if (Options.EnableBurstCompilation && BurstCompilerHelper.IsBurstGenerated)
{
var delegateMethodId = Unity.Burst.LowLevel.BurstCompilerService.CompileAsyncDelegateMethod(delegateObj, string.Empty);
function = Unity.Burst.LowLevel.BurstCompilerService.GetAsyncCompiledAsyncDelegateMethod(delegateMethodId);
}
else
{
// If this is for direct-call, and we're in a player, with Burst disabled, then we should return null,
// since we don't actually have a managedFallbackDelegateMethod at this point.
if (isILPostProcessing)
{
return null;
}
// Make sure that the delegate will never be collected
GCHandle.Alloc(managedFallbackDelegateMethod);
// If we are in a standalone player, and burst is disabled and we are actually
// trying to load a function pointer, in that case we need to support it
// so we are then going to use the managed function directly
// NOTE: When running under IL2CPP, this could lead to a `System.NotSupportedException : To marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition.`
// so in that case, the method needs to have `MonoPInvokeCallback`
// but that's a requirement for IL2CPP, not an issue with burst
function = (void*)Marshal.GetFunctionPointerForDelegate(managedFallbackDelegateMethod);
}
}
#endif
else
{
throw new InvalidOperationException($"Burst cannot compile the function pointer `{methodInfo}` because the `[BurstCompile]` attribute is missing");
}
#endif
// Should not happen but in that case, we are still trying to generated an error
// It can be null if we are trying to compile a function in a standalone player
// and the function was not compiled. In that case, we need to output an error
if (function == null)
{
throw new InvalidOperationException($"Burst failed to compile the function pointer `{methodInfo}`");
}
// When burst compilation is disabled, we are still returning a valid stub function pointer (the a pointer to the managed function)
// so that CompileFunctionPointer actually returns a delegate in all cases
return function;
}
/// <summary>
/// Lets the compiler service know we are shutting down, called by the event on OnDomainUnload, if EditorApplication.quitting was called
/// </summary>
internal static void Shutdown()
{
#if UNITY_EDITOR
SendCommandToCompiler(BurstCompilerOptions.CompilerCommandShutdown);
#endif
}
#if UNITY_EDITOR
internal static void SetDefaultOptions()
{
SendCommandToCompiler(BurstCompilerOptions.CompilerCommandSetDefaultOptions, Options.GetOptions(isForCompilerClient: true));
}
#endif
#if UNITY_EDITOR
// We need this to be queried each domain reload in a static constructor so that it is called on the main thread only!
internal static readonly bool IsScriptDebugInfoEnabled = UnityEditor.Compilation.CompilationPipeline.IsScriptDebugInfoEnabled();
private sealed class DomainReloadStateSingleton : UnityEditor.ScriptableSingleton<DomainReloadStateSingleton>
{
public bool AlreadyLoaded = false;
public bool IsScriptDebugInfoEnabled = false;
}
internal static bool WasScriptDebugInfoEnabledAtDomainReload => DomainReloadStateSingleton.instance.IsScriptDebugInfoEnabled;
internal static void DomainReload()
{
const string parameterSeparator = "***";
const string assemblySeparator = "```";
var isScriptDebugInfoEnabled = IsScriptDebugInfoEnabled;
var cmdBuilder =
BeginCompilerCommand(BurstCompilerOptions.CompilerCommandDomainReload)
.With(ProgressCallbackFunctionPointer)
.With(parameterSeparator)
.With(EagerCompileLogCallbackFunctionPointer)
.With(parameterSeparator)
.With(isScriptDebugInfoEnabled ? "Debug" : "Release")
.With(parameterSeparator);
// We need to send the list of assemblies if
// (a) we have never done that before in this Editor instance, or
// (b) we have done it before, but now the scripting code optimization mode has changed
// from Debug to Release or vice-versa.
// This is because these are the two cases in which CompilerClient will be
// destroyed and recreated.
if (!DomainReloadStateSingleton.instance.AlreadyLoaded ||
DomainReloadStateSingleton.instance.IsScriptDebugInfoEnabled != isScriptDebugInfoEnabled)
{
// Gather list of assemblies to compile (only actually used at Editor startup)
var assemblyNames = UnityEditor.Compilation.CompilationPipeline
.GetAssemblies(UnityEditor.Compilation.AssembliesType.Editor)
.Where(x => File.Exists(x.outputPath)) // If C# compilation fails, it won't exist on disk
.Select(x => $"{x.name}|{string.Join(";", x.defines)}");
foreach (var assemblyName in assemblyNames)
{
cmdBuilder.With(assemblyName)
.With(assemblySeparator);
}
DomainReloadStateSingleton.instance.AlreadyLoaded = true;
DomainReloadStateSingleton.instance.IsScriptDebugInfoEnabled = IsScriptDebugInfoEnabled;
}
cmdBuilder.SendToCompiler();
}
internal static string VersionNotify(string version)
{
return SendCommandToCompiler(BurstCompilerOptions.CompilerCommandVersionNotification, version);
}
internal static string GetTargetCpuFromHost()
{
return SendCommandToCompiler(BurstCompilerOptions.CompilerCommandGetTargetCpuFromHost);
}
#endif
/// <summary>
/// Cancel any compilation being processed by the JIT Compiler in the background.
/// </summary>
internal static void Cancel()
{
#if UNITY_EDITOR
SendCommandToCompiler(BurstCompilerOptions.CompilerCommandCancel);
#endif
}
/// <summary>
/// Check if there is any job pending related to the last compilation ID.
/// </summary>
internal static bool IsCurrentCompilationDone()
{
#if UNITY_EDITOR
return SendCommandToCompiler(BurstCompilerOptions.CompilerCommandIsCurrentCompilationDone) == "True";
#else
return true;
#endif
}
internal static void Enable()
{
#if UNITY_EDITOR
SendCommandToCompiler(BurstCompilerOptions.CompilerCommandEnableCompiler);
#endif
}
internal static void Disable()
{
#if UNITY_EDITOR
SendCommandToCompiler(BurstCompilerOptions.CompilerCommandDisableCompiler);
#endif
}
internal static bool IsHostEditorArm()
{
#if UNITY_EDITOR
return SendCommandToCompiler(BurstCompilerOptions.CompilerCommandIsArmTestEnv)=="true";
#else
return false;
#endif
}
internal static void TriggerUnsafeStaticMethodRecompilation()
{
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
{
var reinitAttributes = asm.GetCustomAttributes().Where(
x => x.GetType().FullName == "Unity.Burst.BurstCompiler+StaticTypeReinitAttribute"
);
foreach (var attribute in reinitAttributes)
{
var ourAttribute = attribute as StaticTypeReinitAttribute;
var type = ourAttribute.reinitType;
var method = type.GetMethod("Constructor",BindingFlags.Static|BindingFlags.Public);
method.Invoke(null, new object[] { });
}
}
}
internal static void TriggerRecompilation()
{
#if UNITY_EDITOR
SetDefaultOptions();
// This is done separately from CompilerCommandTriggerRecompilation below,
// because CompilerCommandTriggerRecompilation will cause all jobs to re-request
// their function pointers from Burst, and we need to have actually triggered
// compilation by that point.
SendCommandToCompiler(BurstCompilerOptions.CompilerCommandTriggerSetupRecompilation);
SendCommandToCompiler(BurstCompilerOptions.CompilerCommandTriggerRecompilation, Options.RequiresSynchronousCompilation.ToString());
#endif
}
internal static void UnloadAdditionalLibraries()
{
SendCommandToCompiler(BurstCompilerOptions.CompilerCommandUnloadBurstNatives);
}
internal static void InitialiseDebuggerHooks()
{
if (IsApiAvailable("BurstManagedDebuggerPluginV1") && String.IsNullOrEmpty(Environment.GetEnvironmentVariable("BURST_DISABLE_DEBUGGER_HOOKS")))
{
SendCommandToCompiler(SendCommandToCompiler(BurstCompilerOptions.CompilerCommandRequestInitialiseDebuggerCommmand));
}
}
internal static bool IsApiAvailable(string apiName)
{
return SendCommandToCompiler(BurstCompilerOptions.CompilerCommandIsNativeApiAvailable, apiName) == "True";
}
internal static int RequestSetProtocolVersion(int version)
{
// Ask editor for the maximum version of the protocol we support, then inform the rest of the systems the negotiated version
var editorVersion = SendCommandToCompiler(BurstCompilerOptions.CompilerCommandRequestSetProtocolVersionEditor, $"{version}");
if (string.IsNullOrEmpty(editorVersion) || !int.TryParse(editorVersion, out var result))
{
result=0;
}
SendCommandToCompiler(BurstCompilerOptions.CompilerCommandSetProtocolVersionBurst, $"{result}");
return result;
}
#if UNITY_EDITOR
private unsafe delegate void LogCallbackDelegate(void* userData, int logType, byte* message, byte* fileName, int lineNumber);
private static unsafe void EagerCompileLogCallback(void* userData, int logType, byte* message, byte* fileName, int lineNumber)
{
if (EagerCompilationLoggingEnabled)
{
BurstRuntime.Log(message, logType, fileName, lineNumber);
}
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate IntPtr ManagedFnPtrResolverDelegate(IntPtr handleVal);
private static IntPtr ManagedResolverFunction(IntPtr handleVal)
{
var delegateObj = GCHandle.FromIntPtr(handleVal).Target;
var fnptr = Marshal.GetFunctionPointerForDelegate(delegateObj);
return fnptr;
}
internal static bool EagerCompilationLoggingEnabled = false;
private static readonly string EagerCompileLogCallbackFunctionPointer;
private static readonly string ManagedResolverFunctionPointer;
#endif
internal static void Initialize(string[] assemblyFolders, string[] ignoreAssemblies)
{
#if UNITY_EDITOR
var glued = new string[2];
glued[0] = SafeStringArrayHelper.SerialiseStringArraySafe(assemblyFolders);
glued[1] = SafeStringArrayHelper.SerialiseStringArraySafe(ignoreAssemblies);
var optionsSet = SafeStringArrayHelper.SerialiseStringArraySafe(glued);
SendCommandToCompiler(BurstCompilerOptions.CompilerCommandInitialize, optionsSet);
#endif
}
internal static void NotifyCompilationStarted(string[] assemblyFolders, string[] ignoreAssemblies)
{
#if UNITY_EDITOR
var glued = new string[2];
glued[0] = SafeStringArrayHelper.SerialiseStringArraySafe(assemblyFolders);
glued[1] = SafeStringArrayHelper.SerialiseStringArraySafe(ignoreAssemblies);
var optionsSet = SafeStringArrayHelper.SerialiseStringArraySafe(glued);
SendCommandToCompiler(BurstCompilerOptions.CompilerCommandNotifyCompilationStarted, optionsSet);
#endif
}
internal static void NotifyAssemblyCompilationNotRequired(string assemblyName)
{
#if UNITY_EDITOR
SendCommandToCompiler(BurstCompilerOptions.CompilerCommandNotifyAssemblyCompilationNotRequired, assemblyName);
#endif
}
internal static void NotifyAssemblyCompilationFinished(string assemblyName, string[] defines)
{
#if UNITY_EDITOR
BeginCompilerCommand(BurstCompilerOptions.CompilerCommandNotifyAssemblyCompilationFinished)
.With(assemblyName).And()
.With(string.Join(";", defines))
.SendToCompiler();
#endif
}
internal static void NotifyCompilationFinished()
{
#if UNITY_EDITOR
SendCommandToCompiler(BurstCompilerOptions.CompilerCommandNotifyCompilationFinished);
#endif
}
internal static string AotCompilation(string[] assemblyFolders, string[] assemblyRoots, string options)
{
var result = "failed";
#if UNITY_EDITOR
result = SendCommandToCompiler(
BurstCompilerOptions.CompilerCommandAotCompilation,
BurstCompilerOptions.SerialiseCompilationOptionsSafe(assemblyRoots, assemblyFolders, options));
#endif
return result;
}
#if UNITY_EDITOR
private static readonly string ProgressCallbackFunctionPointer;
private delegate void ProgressCallbackDelegate(int current, int total);
private static void ProgressCallback(int current, int total)
{
OnProgress?.Invoke(current, total);
}
internal static event Action<int, int> OnProgress;
#endif
internal static void SetProfilerCallbacks()
{
#if UNITY_EDITOR
BeginCompilerCommand(BurstCompilerOptions.CompilerCommandSetProfileCallbacks)
.With(ProfileBeginCallbackFunctionPointer).And(';')
.With(ProfileEndCallbackFunctionPointer)
.SendToCompiler();
#endif
}
#if UNITY_EDITOR
internal delegate void ProfileBeginCallbackDelegate(string markerName, string metadataName, string metadataValue);
internal delegate void ProfileEndCallbackDelegate(string markerName);
private static readonly string ProfileBeginCallbackFunctionPointer;
private static readonly string ProfileEndCallbackFunctionPointer;
private static void ProfileBeginCallback(string markerName, string metadataName, string metadataValue) => OnProfileBegin?.Invoke(markerName, metadataName, metadataValue);
private static void ProfileEndCallback(string markerName) => OnProfileEnd?.Invoke(markerName);
internal static event ProfileBeginCallbackDelegate OnProfileBegin;
internal static event ProfileEndCallbackDelegate OnProfileEnd;
#endif
private static string SendRawCommandToCompiler(string command)
{
var results = Unity.Burst.LowLevel.BurstCompilerService.GetDisassembly(DummyMethodInfo, command);
if (!string.IsNullOrEmpty(results))
return results.TrimStart('\n');
return "";
}
private static string SendCommandToCompiler(string commandName, string commandArgs = null)
{
if (commandName == null) throw new ArgumentNullException(nameof(commandName));
if (commandArgs == null)
{
// If there are no arguments then there's no reason to go through the builder
return SendRawCommandToCompiler(commandName);
}
// Otherwise use the builder for building the final command
return BeginCompilerCommand(commandName)
.With(commandArgs)
.SendToCompiler();
}
private static readonly MethodInfo DummyMethodInfo = typeof(BurstCompiler).GetMethod(nameof(DummyMethod), BindingFlags.Static | BindingFlags.NonPublic);
/// <summary>
/// Dummy empty method for being able to send a command to the compiler
/// </summary>
private static void DummyMethod() { }
#if !UNITY_EDITOR && !BURST_INTERNAL
/// <summary>
/// Internal class to detect at standalone player time if AOT settings were enabling burst.
/// </summary>
[BurstCompile]
internal static class BurstCompilerHelper
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate bool IsBurstEnabledDelegate();
private static readonly IsBurstEnabledDelegate IsBurstEnabledImpl = new IsBurstEnabledDelegate(IsBurstEnabled);
[BurstCompile]
[AOT.MonoPInvokeCallback(typeof(IsBurstEnabledDelegate))]
private static bool IsBurstEnabled()
{
bool result = true;
DiscardedMethod(ref result);
return result;
}
[BurstDiscard]
private static void DiscardedMethod(ref bool value)
{
value = false;
}
private static unsafe bool IsCompiledByBurst(Delegate del)
{
var delegateMethodId = Unity.Burst.LowLevel.BurstCompilerService.CompileAsyncDelegateMethod(del, string.Empty);
// We don't try to run the method, having a pointer is already enough to tell us that burst was active for AOT settings
return Unity.Burst.LowLevel.BurstCompilerService.GetAsyncCompiledAsyncDelegateMethod(delegateMethodId) != (void*)0;
}
/// <summary>
/// Gets a boolean indicating whether burst was enabled for standalone player, used only at runtime.
/// </summary>
public static readonly bool IsBurstGenerated = IsCompiledByBurst(IsBurstEnabledImpl);
}
#endif // !UNITY_EDITOR && !BURST_INTERNAL
/// <summary>
/// Fake delegate class to make BurstCompilerService.CompileAsyncDelegateMethod happy
/// so that it can access the underlying static method via the property get_Method.
/// So this class is not a delegate.
/// </summary>
private class FakeDelegate
{
public FakeDelegate(MethodInfo method)
{
Method = method;
}
[Preserve]
public MethodInfo Method { get; }
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1ec7023d81033de6aa77e32be8ea9352
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,931 @@
using System;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
#if BURST_COMPILER_SHARED
using Burst.Compiler.IL.Helpers;
#else
using Unity.Jobs.LowLevel.Unsafe;
using Unity.Burst;
#endif
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// NOTE: This file is shared via a csproj cs link in Burst.Compiler.IL
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
namespace Unity.Burst
{
internal enum GlobalSafetyChecksSettingKind
{
Off = 0,
On = 1,
ForceOn = 2,
}
/// <summary>
/// Options available at Editor time and partially at runtime to control the behavior of the compilation and to enable/disable burst jobs.
/// </summary>
#if BURST_COMPILER_SHARED
internal sealed partial class BurstCompilerOptionsInternal
#else
public sealed partial class BurstCompilerOptions
#endif
{
private const string DisableCompilationArg = "--burst-disable-compilation";
private const string ForceSynchronousCompilationArg = "--burst-force-sync-compilation";
internal const string DefaultLibraryName = "lib_burst_generated";
internal const string BurstInitializeName = "burst.initialize";
internal const string BurstInitializeExternalsName = "burst.initialize.externals";
internal const string BurstInitializeStaticsName = "burst.initialize.statics";
#if BURST_COMPILER_SHARED || UNITY_EDITOR
internal static readonly string DefaultCacheFolder = Path.Combine(Environment.CurrentDirectory, "Library", "BurstCache", "JIT");
internal const string DeleteCacheMarkerFileName = "DeleteCache.txt";
#endif
#if UNITY_EDITOR
private static readonly string BackendNameOverride = Environment.GetEnvironmentVariable("UNITY_BURST_BACKEND_NAME_OVERRIDE");
#endif
// -------------------------------------------------------
// Common options used by the compiler
// -------------------------------------------------------
internal const string OptionBurstcSwitch = "+burstc";
internal const string OptionGroup = "group";
internal const string OptionPlatform = "platform=";
internal const string OptionBackend = "backend=";
internal const string OptionGlobalSafetyChecksSetting = "global-safety-checks-setting=";
internal const string OptionDisableSafetyChecks = "disable-safety-checks";
internal const string OptionDisableOpt = "disable-opt";
internal const string OptionFastMath = "fastmath";
internal const string OptionTarget = "target=";
internal const string OptionOptLevel = "opt-level=";
internal const string OptionLogTimings = "log-timings";
internal const string OptionOptForSize = "opt-for-size";
internal const string OptionFloatPrecision = "float-precision=";
internal const string OptionFloatMode = "float-mode=";
internal const string OptionBranchProtection = "branch-protection=";
internal const string OptionDisableWarnings = "disable-warnings=";
internal const string OptionAssemblyDefines = "assembly-defines=";
internal const string OptionDump = "dump=";
internal const string OptionFormat = "format=";
internal const string OptionDebugTrap = "debugtrap";
internal const string OptionDisableVectors = "disable-vectors";
internal const string OptionDebug = "debug=";
internal const string OptionDebugMode = "debugMode";
internal const string OptionStaticLinkage = "generate-static-linkage-methods";
internal const string OptionJobMarshalling = "generate-job-marshalling-methods";
internal const string OptionTempDirectory = "temp-folder=";
internal const string OptionEnableDirectExternalLinking = "enable-direct-external-linking";
internal const string OptionLinkerOptions = "linker-options=";
internal const string OptionEnableAutoLayoutFallbackCheck = "enable-autolayout-fallback-check";
internal const string OptionGenerateLinkXml = "generate-link-xml=";
internal const string OptionMetaDataGeneration = "meta-data-generation=";
internal const string OptionDisableStringInterpolationInExceptionMessages = "disable-string-interpolation-in-exception-messages";
internal const string OptionPlatformConfiguration = "platform-configuration=";
// -------------------------------------------------------
// Options used by the Jit and Bcl compilers
// -------------------------------------------------------
internal const string OptionCacheDirectory = "cache-directory=";
// -------------------------------------------------------
// Options used by the Jit compiler
// -------------------------------------------------------
internal const string OptionJitDisableFunctionCaching = "disable-function-caching";
internal const string OptionJitDisableAssemblyCaching = "disable-assembly-caching";
internal const string OptionJitEnableAssemblyCachingLogs = "enable-assembly-caching-logs";
internal const string OptionJitEnableSynchronousCompilation = "enable-synchronous-compilation";
internal const string OptionJitCompilationPriority = "compilation-priority=";
internal const string OptionJitIsForFunctionPointer = "is-for-function-pointer";
internal const string OptionJitManagedFunctionPointer = "managed-function-pointer=";
internal const string OptionJitManagedDelegateHandle = "managed-delegate-handle=";
internal const string OptionEnableInterpreter = "enable-interpreter";
// -------------------------------------------------------
// Options used by the Aot compiler
// -------------------------------------------------------
internal const string OptionAotAssemblyFolder = "assembly-folder=";
internal const string OptionRootAssembly = "root-assembly=";
internal const string OptionIncludeRootAssemblyReferences = "include-root-assembly-references=";
internal const string OptionAotMethod = "method=";
internal const string OptionAotType = "type=";
internal const string OptionAotAssembly = "assembly=";
internal const string OptionAotOutputPath = "output=";
internal const string OptionAotKeepIntermediateFiles = "keep-intermediate-files";
internal const string OptionAotNoLink = "nolink";
internal const string OptionAotOnlyStaticMethods = "only-static-methods";
internal const string OptionMethodPrefix = "method-prefix=";
internal const string OptionAotNoNativeToolchain = "no-native-toolchain";
internal const string OptionAotEmitLlvmObjects = "emit-llvm-objects";
internal const string OptionAotKeyFolder = "key-folder=";
internal const string OptionAotDecodeFolder = "decode-folder=";
internal const string OptionVerbose = "verbose";
internal const string OptionValidateExternalToolChain = "validate-external-tool-chain";
internal const string OptionCompilerThreads = "threads=";
internal const string OptionChunkSize = "chunk-size=";
internal const string OptionPrintLogOnMissingPInvokeCallbackAttribute = "print-monopinvokecallbackmissing-message";
internal const string OptionOutputMode = "output-mode=";
internal const string OptionAlwaysCreateOutput = "always-create-output=";
internal const string OptionAotPdbSearchPaths = "pdb-search-paths=";
internal const string OptionSafetyChecks = "safety-checks";
internal const string OptionLibraryOutputMode = "library-output-mode=";
internal const string OptionCompilationId = "compilation-id=";
internal const string OptionTargetFramework = "target-framework=";
internal const string OptionDiscardAssemblies = "discard-assemblies=";
internal const string OptionSaveExtraContext = "save-extra-context";
internal const string CompilerCommandShutdown = "$shutdown";
internal const string CompilerCommandCancel = "$cancel";
internal const string CompilerCommandEnableCompiler = "$enable_compiler";
internal const string CompilerCommandDisableCompiler = "$disable_compiler";
internal const string CompilerCommandSetDefaultOptions = "$set_default_options";
internal const string CompilerCommandTriggerSetupRecompilation = "$trigger_setup_recompilation";
internal const string CompilerCommandIsCurrentCompilationDone = "$is_current_compilation_done";
// This one is annoying special - the Unity editor has a detection for this string being in the command and does some
// job specific logic - meaning that we **cannot** have this string be present in any other command or bugs will occur.
internal const string CompilerCommandTriggerRecompilation = "$trigger_recompilation";
internal const string CompilerCommandInitialize = "$initialize";
internal const string CompilerCommandDomainReload = "$domain_reload";
internal const string CompilerCommandVersionNotification = "$version";
internal const string CompilerCommandGetTargetCpuFromHost = "$get_target_cpu_from_host";
internal const string CompilerCommandSetProfileCallbacks = "$set_profile_callbacks";
internal const string CompilerCommandUnloadBurstNatives = "$unload_burst_natives";
internal const string CompilerCommandIsNativeApiAvailable = "$is_native_api_available";
internal const string CompilerCommandILPPCompilation = "$ilpp_compilation";
internal const string CompilerCommandIsArmTestEnv = "$is_arm_test_env";
internal const string CompilerCommandNotifyAssemblyCompilationNotRequired = "$notify_assembly_compilation_not_required";
internal const string CompilerCommandNotifyAssemblyCompilationFinished = "$notify_assembly_compilation_finished";
internal const string CompilerCommandNotifyCompilationStarted = "$notify_compilation_started";
internal const string CompilerCommandNotifyCompilationFinished = "$notify_compilation_finished";
internal const string CompilerCommandAotCompilation = "$aot_compilation";
internal const string CompilerCommandRequestInitialiseDebuggerCommmand = "$request_debug_command";
internal const string CompilerCommandInitialiseDebuggerCommmand = "$load_debugger_interface";
internal const string CompilerCommandRequestSetProtocolVersionEditor = "$request_set_protocol_version_editor";
internal const string CompilerCommandSetProtocolVersionBurst = "$set_protocol_version_burst";
internal static string SerialiseCompilationOptionsSafe(string[] roots, string[] folders, string options)
{
var finalSerialise = new string[3];
finalSerialise[0] = SafeStringArrayHelper.SerialiseStringArraySafe(roots);
finalSerialise[1] = SafeStringArrayHelper.SerialiseStringArraySafe(folders);
finalSerialise[2] = options;
return SafeStringArrayHelper.SerialiseStringArraySafe(finalSerialise);
}
internal static (string[] roots, string[] folders, string options) DeserialiseCompilationOptionsSafe(string from)
{
var set = SafeStringArrayHelper.DeserialiseStringArraySafe(from);
return (SafeStringArrayHelper.DeserialiseStringArraySafe(set[0]), SafeStringArrayHelper.DeserialiseStringArraySafe(set[1]), set[2]);
}
// All the following content is exposed to the public interface
#if !BURST_COMPILER_SHARED
// These fields are only setup at startup
internal static readonly bool ForceDisableBurstCompilation;
private static readonly bool ForceBurstCompilationSynchronously;
internal static readonly bool IsSecondaryUnityProcess;
#if UNITY_EDITOR
internal bool IsInitializing;
#endif
private bool _enableBurstCompilation;
private bool _enableBurstCompileSynchronously;
private bool _enableBurstSafetyChecks;
private bool _enableBurstTimings;
private bool _enableBurstDebug;
private bool _forceEnableBurstSafetyChecks;
private BurstCompilerOptions() : this(false)
{
}
internal BurstCompilerOptions(bool isGlobal)
{
#if UNITY_EDITOR
IsInitializing = true;
#endif
try
{
IsGlobal = isGlobal;
// By default, burst is enabled as well as safety checks
EnableBurstCompilation = true;
EnableBurstSafetyChecks = true;
}
finally
{
#if UNITY_EDITOR
IsInitializing = false;
#endif
}
}
/// <summary>
/// <c>true</c> if this option is the global options that affects menus
/// </summary>
private bool IsGlobal { get; }
/// <summary>
/// Gets a boolean indicating whether burst is enabled.
/// </summary>
public bool IsEnabled
{
get => EnableBurstCompilation && !ForceDisableBurstCompilation;
}
/// <summary>
/// Gets or sets a boolean to enable or disable compilation of burst jobs.
/// </summary>
public bool EnableBurstCompilation
{
get => _enableBurstCompilation;
set
{
// If we are in the global settings, and we are forcing to no burst compilation
if (IsGlobal && ForceDisableBurstCompilation) value = false;
bool changed = _enableBurstCompilation != value;
_enableBurstCompilation = value;
// Modify only JobsUtility.JobCompilerEnabled when modifying global settings
if (IsGlobal)
{
#if !BURST_INTERNAL
// We need also to disable jobs as functions are being cached by the job system
// and when we ask for disabling burst, we are also asking the job system
// to no longer use the cached functions
JobsUtility.JobCompilerEnabled = value;
#if UNITY_EDITOR
if (changed)
{
// Send the command to the compiler service
if (value)
{
BurstCompiler.Enable();
MaybeTriggerRecompilation();
}
else
{
BurstCompiler.Disable();
}
}
#endif
#endif
// Store the option directly into BurstCompiler.IsEnabled
BurstCompiler._IsEnabled = value;
}
if (changed)
{
OnOptionsChanged();
}
}
}
/// <summary>
/// Gets or sets a boolean to force the compilation of all burst jobs synchronously.
/// </summary>
/// <remarks>
/// This is only available at Editor time. Does not have an impact on player mode.
/// </remarks>
public bool EnableBurstCompileSynchronously
{
get => _enableBurstCompileSynchronously;
set
{
bool changed = _enableBurstCompileSynchronously != value;
_enableBurstCompileSynchronously = value;
if (changed) OnOptionsChanged();
}
}
/// <summary>
/// Gets or sets a boolean to enable or disable safety checks.
/// </summary>
/// <remarks>
/// This is only available at Editor time. Does not have an impact on player mode.
/// </remarks>
public bool EnableBurstSafetyChecks
{
get => _enableBurstSafetyChecks;
set
{
bool changed = _enableBurstSafetyChecks != value;
_enableBurstSafetyChecks = value;
if (changed)
{
OnOptionsChanged();
MaybeTriggerRecompilation();
}
}
}
/// <summary>
/// Gets or sets a boolean to force enable safety checks, irrespective of what
/// <c>EnableBurstSafetyChecks</c> is set to, or whether the job or function
/// has <c>DisableSafetyChecks</c> set.
/// </summary>
/// <remarks>
/// This is only available at Editor time. Does not have an impact on player mode.
/// </remarks>
public bool ForceEnableBurstSafetyChecks
{
get => _forceEnableBurstSafetyChecks;
set
{
bool changed = _forceEnableBurstSafetyChecks != value;
_forceEnableBurstSafetyChecks = value;
if (changed)
{
OnOptionsChanged();
MaybeTriggerRecompilation();
}
}
}
/// <summary>
/// Enable debugging mode
/// </summary>
public bool EnableBurstDebug
{
get => _enableBurstDebug;
set
{
bool changed = _enableBurstDebug != value;
_enableBurstDebug = value;
if (changed)
{
OnOptionsChanged();
MaybeTriggerRecompilation();
}
}
}
/// <summary>
/// This property is no longer used and will be removed in a future major release.
/// </summary>
[Obsolete("This property is no longer used and will be removed in a future major release")]
public bool DisableOptimizations
{
get => false;
set
{
}
}
/// <summary>
/// This property is no longer used and will be removed in a future major release. Use the [BurstCompile(FloatMode = FloatMode.Fast)] on the method directly to enable this feature
/// </summary>
[Obsolete("This property is no longer used and will be removed in a future major release. Use the [BurstCompile(FloatMode = FloatMode.Fast)] on the method directly to enable this feature")]
public bool EnableFastMath
{
get => true;
set
{
// ignored
}
}
internal bool EnableBurstTimings
{
get => _enableBurstTimings;
set
{
bool changed = _enableBurstTimings != value;
_enableBurstTimings = value;
if (changed) OnOptionsChanged();
}
}
internal bool RequiresSynchronousCompilation => EnableBurstCompileSynchronously || ForceBurstCompilationSynchronously;
internal Action OptionsChanged { get; set; }
internal BurstCompilerOptions Clone()
{
// WARNING: for some reason MemberwiseClone() is NOT WORKING on Mono/Unity
// so we are creating a manual clone
var clone = new BurstCompilerOptions
{
EnableBurstCompilation = EnableBurstCompilation,
EnableBurstCompileSynchronously = EnableBurstCompileSynchronously,
EnableBurstSafetyChecks = EnableBurstSafetyChecks,
EnableBurstTimings = EnableBurstTimings,
EnableBurstDebug = EnableBurstDebug,
ForceEnableBurstSafetyChecks = ForceEnableBurstSafetyChecks,
};
return clone;
}
private static bool TryGetAttribute(MemberInfo member, out BurstCompileAttribute attribute)
{
attribute = null;
// We don't fail if member == null as this method is being called by native code and doesn't expect to crash
if (member == null)
{
return false;
}
// Fetch options from attribute
attribute = GetBurstCompileAttribute(member);
if (attribute == null)
{
return false;
}
return true;
}
private static bool TryGetAttribute(Assembly assembly, out BurstCompileAttribute attribute)
{
// We don't fail if assembly == null as this method is being called by native code and doesn't expect to crash
if (assembly == null)
{
attribute = null;
return false;
}
// Fetch options from attribute
attribute = assembly.GetCustomAttribute<BurstCompileAttribute>();
return attribute != null;
}
private static BurstCompileAttribute GetBurstCompileAttribute(MemberInfo memberInfo)
{
var result = memberInfo.GetCustomAttribute<BurstCompileAttribute>();
if (result != null)
{
return result;
}
foreach (var a in memberInfo.GetCustomAttributes())
{
var attributeType = a.GetType();
if (attributeType.FullName == "Burst.Compiler.IL.Tests.TestCompilerAttribute")
{
var options = new List<string>();
return new BurstCompileAttribute(FloatPrecision.Standard, FloatMode.Default)
{
CompileSynchronously = true,
Options = options.ToArray(),
};
}
}
return null;
}
internal static bool HasBurstCompileAttribute(MemberInfo member)
{
if (member == null) throw new ArgumentNullException(nameof(member));
BurstCompileAttribute attr;
return TryGetAttribute(member, out attr);
}
/// <summary>
/// Merges the attributes from the assembly into the member attribute, such that if any field of the member attribute
/// was not specifically set by the user (or is a default), the assembly level setting is used for the Burst compilation.
/// </summary>
internal static void MergeAttributes(ref BurstCompileAttribute memberAttribute, in BurstCompileAttribute assemblyAttribute)
{
if (memberAttribute.FloatMode == FloatMode.Default)
{
memberAttribute.FloatMode = assemblyAttribute.FloatMode;
}
if (memberAttribute.FloatPrecision == FloatPrecision.Standard)
{
memberAttribute.FloatPrecision = assemblyAttribute.FloatPrecision;
}
if (memberAttribute.OptimizeFor == OptimizeFor.Default)
{
memberAttribute.OptimizeFor = assemblyAttribute.OptimizeFor;
}
if (!memberAttribute._compileSynchronously.HasValue && assemblyAttribute._compileSynchronously.HasValue)
{
memberAttribute._compileSynchronously = assemblyAttribute._compileSynchronously;
}
if (!memberAttribute._debug.HasValue && assemblyAttribute._debug.HasValue)
{
memberAttribute._debug = assemblyAttribute._debug;
}
if (!memberAttribute._disableDirectCall.HasValue && assemblyAttribute._disableDirectCall.HasValue)
{
memberAttribute._disableDirectCall = assemblyAttribute._disableDirectCall;
}
if (!memberAttribute._disableSafetyChecks.HasValue && assemblyAttribute._disableSafetyChecks.HasValue)
{
memberAttribute._disableSafetyChecks = assemblyAttribute._disableSafetyChecks;
}
}
/// <summary>
/// Gets the options for the specified member. Returns <c>false</c> if the `[BurstCompile]` attribute was not found.
/// </summary>
/// <returns><c>false</c> if the `[BurstCompile]` attribute was not found; otherwise <c>true</c></returns>
internal bool TryGetOptions(MemberInfo member, out string flagsOut, bool isForILPostProcessing = false, bool isForCompilerClient = false)
{
flagsOut = null;
if (!TryGetAttribute(member, out var memberAttribute))
{
return false;
}
if (TryGetAttribute(member.Module.Assembly, out var assemblyAttribute))
{
MergeAttributes(ref memberAttribute, in assemblyAttribute);
}
flagsOut = GetOptions(memberAttribute, isForILPostProcessing, isForCompilerClient);
return true;
}
internal string GetOptions(BurstCompileAttribute attr = null, bool isForILPostProcessing = false, bool isForCompilerClient = false)
{
// Add debug to Jit options instead of passing it here
// attr.Debug
var flagsBuilderOut = new StringBuilder();
if (!isForCompilerClient && ((attr?.CompileSynchronously ?? false) || RequiresSynchronousCompilation))
{
AddOption(flagsBuilderOut, GetOption(OptionJitEnableSynchronousCompilation));
}
AddOption(flagsBuilderOut, GetOption(OptionDebug,
#if UNITY_EDITOR
BurstCompiler.IsScriptDebugInfoEnabled && EnableBurstDebug ? "Full" : "LineOnly"
#else
"LineOnly"
#endif
));
if (isForILPostProcessing)
{
// IL Post Processing compiles are the only thing set to low priority.
AddOption(flagsBuilderOut, GetOption(OptionJitCompilationPriority, CompilationPriority.ILPP));
}
if (attr != null)
{
if (attr.FloatMode != FloatMode.Default)
{
AddOption(flagsBuilderOut, GetOption(OptionFloatMode, attr.FloatMode));
}
if (attr.FloatPrecision != FloatPrecision.Standard)
{
AddOption(flagsBuilderOut, GetOption(OptionFloatPrecision, attr.FloatPrecision));
}
// We disable safety checks for jobs with `[BurstCompile(DisableSafetyChecks = true)]`.
if (attr.DisableSafetyChecks)
{
AddOption(flagsBuilderOut, GetOption(OptionDisableSafetyChecks));
}
if (attr.Options != null)
{
foreach (var option in attr.Options)
{
if (!string.IsNullOrEmpty(option))
{
AddOption(flagsBuilderOut, option);
}
}
}
switch (attr.OptimizeFor)
{
case OptimizeFor.Default:
case OptimizeFor.Balanced:
AddOption(flagsBuilderOut, GetOption(OptionOptLevel, 2));
break;
case OptimizeFor.Performance:
AddOption(flagsBuilderOut, GetOption(OptionOptLevel, 3));
break;
case OptimizeFor.Size:
AddOption(flagsBuilderOut, GetOption(OptionOptForSize));
AddOption(flagsBuilderOut, GetOption(OptionOptLevel, 3));
break;
case OptimizeFor.FastCompilation:
AddOption(flagsBuilderOut, GetOption(OptionOptLevel, 1));
break;
}
}
if (ForceEnableBurstSafetyChecks)
{
AddOption(flagsBuilderOut, GetOption(OptionGlobalSafetyChecksSetting, GlobalSafetyChecksSettingKind.ForceOn));
}
else if (EnableBurstSafetyChecks)
{
AddOption(flagsBuilderOut, GetOption(OptionGlobalSafetyChecksSetting, GlobalSafetyChecksSettingKind.On));
}
else
{
AddOption(flagsBuilderOut, GetOption(OptionGlobalSafetyChecksSetting, GlobalSafetyChecksSettingKind.Off));
}
if (EnableBurstTimings)
{
AddOption(flagsBuilderOut, GetOption(OptionLogTimings));
}
if (EnableBurstDebug || (attr?.Debug ?? false))
{
AddOption(flagsBuilderOut, GetOption(OptionDebugMode));
}
#if UNITY_EDITOR
if (BackendNameOverride != null)
{
AddOption(flagsBuilderOut, GetOption(OptionBackend, BackendNameOverride));
}
#endif
AddOption(flagsBuilderOut, GetOption(OptionTempDirectory, Path.Combine(Environment.CurrentDirectory, "Temp", "Burst")));
return flagsBuilderOut.ToString();
}
private static void AddOption(StringBuilder builder, string option)
{
if (builder.Length != 0)
builder.Append('\n'); // Use \n to separate options
builder.Append(option);
}
internal static string GetOption(string optionName, object value = null)
{
if (optionName == null) throw new ArgumentNullException(nameof(optionName));
return "--" + optionName + (value ?? String.Empty);
}
private void OnOptionsChanged()
{
OptionsChanged?.Invoke();
}
private void MaybeTriggerRecompilation()
{
#if UNITY_EDITOR
if (IsGlobal && IsEnabled && !IsInitializing)
{
UnityEditor.EditorUtility.DisplayProgressBar("Burst", "Waiting for compilation to finish", -1);
try
{
BurstCompiler.TriggerRecompilation();
}
finally
{
UnityEditor.EditorUtility.ClearProgressBar();
}
}
#endif
}
#if !UNITY_DOTSPLAYER
/// <summary>
/// Static initializer based on command line arguments
/// </summary>
static BurstCompilerOptions()
{
foreach (var arg in Environment.GetCommandLineArgs())
{
switch (arg)
{
case DisableCompilationArg:
ForceDisableBurstCompilation = true;
break;
case ForceSynchronousCompilationArg:
ForceBurstCompilationSynchronously = true;
break;
}
}
if (CheckIsSecondaryUnityProcess())
{
ForceDisableBurstCompilation = true;
IsSecondaryUnityProcess = true;
}
var disableCompilation = Environment.GetEnvironmentVariable("UNITY_BURST_DISABLE_COMPILATION");
if (!string.IsNullOrEmpty(disableCompilation) && disableCompilation != "0")
{
ForceDisableBurstCompilation = true;
}
#if UNITY_EDITOR && ENABLE_CORECLR
ForceDisableBurstCompilation = true;
#endif
}
private static bool CheckIsSecondaryUnityProcess()
{
#if UNITY_EDITOR
#if UNITY_2021_1_OR_NEWER
if (UnityEditor.MPE.ProcessService.level == UnityEditor.MPE.ProcessLevel.Secondary
|| UnityEditor.AssetDatabase.IsAssetImportWorkerProcess())
{
return true;
}
#else
if (UnityEditor.MPE.ProcessService.level == UnityEditor.MPE.ProcessLevel.Slave
|| UnityEditor.AssetDatabase.IsAssetImportWorkerProcess())
{
return true;
}
#endif
#endif
return false;
}
#endif
#endif // !BURST_COMPILER_SHARED
}
#if UNITY_EDITOR
// NOTE: This must be synchronized with Backend.TargetPlatform
internal enum TargetPlatform
{
Windows = 0,
macOS = 1,
Linux = 2,
Android = 3,
iOS = 4,
PS4 = 5,
XboxOne_Deprecated = 6,
WASM = 7,
UWP = 8,
Lumin = 9,
Switch = 10,
Stadia_Deprecated = 11,
tvOS = 12,
EmbeddedLinux = 13,
GameCoreXboxOne = 14,
GameCoreXboxSeries = 15,
PS5 = 16,
QNX = 17,
visionOS = 18,
visionSimulator = 19,
}
#endif
// Don't expose the enum in Burst.Compiler.IL, need only in Unity.Burst.dll which is referenced by Burst.Compiler.IL.Tests
#if !BURST_COMPILER_SHARED
// Make the enum public for btests via Unity.Burst.dll; leave it internal in the package
#if BURST_INTERNAL
public
#else
internal
#endif
// NOTE: This must be synchronized with Backend.TargetCpu
enum BurstTargetCpu
{
Auto = 0,
X86_SSE2 = 1,
X86_SSE4 = 2,
X64_SSE2 = 3,
X64_SSE4 = 4,
AVX = 5,
AVX2 = 6,
WASM32 = 7,
ARMV7A_NEON32 = 8,
ARMV8A_AARCH64 = 9,
THUMB2_NEON32 = 10,
ARMV8A_AARCH64_HALFFP = 11,
ARMV9A = 12,
}
#endif
/// <summary>
/// Flags used by <see cref="NativeCompiler.CompileMethod"/> to dump intermediate compiler results.
/// Note please ensure MonoDebuggerHandling/Constants.h is updated if you change this enum
/// </summary>
[Flags]
#if BURST_COMPILER_SHARED
public enum NativeDumpFlags
#else
internal enum NativeDumpFlags
#endif
{
/// <summary>
/// Nothing is selected.
/// </summary>
None = 0,
/// <summary>
/// Dumps the IL of the method being compiled
/// </summary>
IL = 1 << 0,
/// <summary>
/// Unused dump state.
/// </summary>
Unused = 1 << 1,
/// <summary>
/// Dumps the generated module without optimizations
/// </summary>
IR = 1 << 2,
/// <summary>
/// Dumps the generated backend code after optimizations (if enabled)
/// </summary>
IROptimized = 1 << 3,
/// <summary>
/// Dumps the generated ASM code
/// </summary>
Asm = 1 << 4,
/// <summary>
/// Generate the native code
/// </summary>
Function = 1 << 5,
/// <summary>
/// Dumps the result of analysis
/// </summary>
Analysis = 1 << 6,
/// <summary>
/// Dumps the diagnostics from optimisation
/// </summary>
IRPassAnalysis = 1 << 7,
/// <summary>
/// Dumps the IL before all transformation of the method being compiled
/// </summary>
ILPre = 1 << 8,
/// <summary>
/// Dumps the per-entry-point module
/// </summary>
IRPerEntryPoint = 1 << 9,
/// <summary>
/// Dumps all normal output.
/// </summary>
All = IL | ILPre | IR | IROptimized | IRPerEntryPoint | Asm | Function | Analysis | IRPassAnalysis
}
#if BURST_COMPILER_SHARED
public enum CompilationPriority
#else
internal enum CompilationPriority
#endif
{
EagerCompilationSynchronous = 0,
Asynchronous = 1,
ILPP = 2,
EagerCompilationAsynchronous = 3,
}
#if UNITY_EDITOR
/// <summary>
/// Some options cannot be applied until after an Editor restart, in Editor versions prior to 2019.3.
/// This class assists with allowing the relevant settings to be changed via the menu,
/// followed by displaying a message to the user to say a restart is necessary.
/// </summary>
internal static class RequiresRestartUtility
{
[ThreadStatic]
public static bool CalledFromUI;
[ThreadStatic]
public static bool RequiresRestart;
}
#endif
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ebefffdd15ef3832ab7ae2b21e549832
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,24 @@
#if UNITY_2019_3_OR_NEWER
namespace Unity.Burst
{
/// <summary>
/// Represents the types of compiled code that are run on the current thread.
/// </summary>
public enum BurstExecutionEnvironment
{
/// <summary>
/// Use the default (aka FloatMode specified via Compile Attribute - <see cref="FloatMode"/>
/// </summary>
Default=0,
/// <summary>
/// Override the specified float mode and run the non deterministic version
/// </summary>
NonDeterministic=0,
/// <summary>
/// Override the specified float mode and run the deterministic version
/// </summary>
Deterministic=1,
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b85cbcd785ff3b1597b89eb2c453f4fe
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,180 @@
using System;
using System.Diagnostics;
#if !BURST_COMPILER_SHARED
using Unity.Jobs.LowLevel.Unsafe;
#endif
namespace Unity.Burst
{
/// <summary>
/// Provides helper intrinsics that can be used at runtime.
/// </summary>
#if BURST_COMPILER_SHARED
internal static class BurstRuntimeInternal
#else
public static class BurstRuntime
#endif
{
/// <summary>
/// Gets a 32-bits hashcode from a type computed for the <see cref="System.Type.AssemblyQualifiedName"/>
/// </summary>
/// <typeparam name="T">The type to compute the hash from</typeparam>
/// <returns>The 32-bit hashcode.</returns>
public static int GetHashCode32<T>()
{
return HashCode32<T>.Value;
}
/// <summary>
/// Gets a 32-bits hashcode from a type computed for the <see cref="System.Type.AssemblyQualifiedName"/>
/// This method cannot be used from a burst job.
/// </summary>
/// <param name="type">The type to compute the hash from</param>
/// <returns>The 32-bit hashcode.</returns>
public static int GetHashCode32(Type type)
{
return HashStringWithFNV1A32(type.AssemblyQualifiedName);
}
/// <summary>
/// Gets a 64-bits hashcode from a type computed for the <see cref="System.Type.AssemblyQualifiedName"/>
/// </summary>
/// <typeparam name="T">The type to compute the hash from</typeparam>
/// <returns>The 64-bit hashcode.</returns>
public static long GetHashCode64<T>()
{
return HashCode64<T>.Value;
}
/// <summary>
/// Gets a 64-bits hashcode from a type computed for the <see cref="System.Type.AssemblyQualifiedName"/>.
/// This method cannot be used from a burst job.
/// </summary>
/// <param name="type">Type to calculate a hash for</param>
/// <returns>The 64-bit hashcode.</returns>
public static long GetHashCode64(Type type)
{
return HashStringWithFNV1A64(type.AssemblyQualifiedName);
}
// method internal as it is used by the compiler directly
internal static int HashStringWithFNV1A32(string text)
{
// Using http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-1a
// with basis and prime:
const uint offsetBasis = 2166136261;
const uint prime = 16777619;
uint result = offsetBasis;
foreach (var c in text)
{
result = prime * (result ^ (byte)(c & 255));
result = prime * (result ^ (byte)(c >> 8));
}
return (int)result;
}
// method internal as it is used by the compiler directly
// WARNING: This **must** be kept in sync with the definition in ILPostProcessing.cs!
internal static long HashStringWithFNV1A64(string text)
{
// Using http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-1a
// with basis and prime:
const ulong offsetBasis = 14695981039346656037;
const ulong prime = 1099511628211;
ulong result = offsetBasis;
foreach (var c in text)
{
result = prime * (result ^ (byte)(c & 255));
result = prime * (result ^ (byte)(c >> 8));
}
return (long)result;
}
private struct HashCode32<T>
{
public static readonly int Value = HashStringWithFNV1A32(typeof(T).AssemblyQualifiedName);
}
private struct HashCode64<T>
{
public static readonly long Value = HashStringWithFNV1A64(typeof(T).AssemblyQualifiedName);
}
#if !BURST_COMPILER_SHARED
/// <summary>
/// Allows for loading additional Burst native libraries
/// Important: Designed for Play mode / Desktop Standalone Players ONLY
/// In Editor, any libraries that have been loaded will be unloaded on exit of playmode
/// Only supported from 2021.1 and later. You can use BurstCompiler.IsLoadAdditionalLibrarySupported() to confirm it is available.
/// </summary>
/// <param name="pathToLibBurstGenerated">Absolute filesystem location of bursted library to load</param>
/// <returns>true if the library was loaded successfully</returns>
public static bool LoadAdditionalLibrary(string pathToLibBurstGenerated)
{
if (BurstCompiler.IsLoadAdditionalLibrarySupported())
{
return LoadAdditionalLibraryInternal(pathToLibBurstGenerated);
}
return false;
}
internal static bool LoadAdditionalLibraryInternal(string pathToLibBurstGenerated)
{
return (bool)typeof(Unity.Burst.LowLevel.BurstCompilerService).GetMethod("LoadBurstLibrary").Invoke(null, new object[] { pathToLibBurstGenerated });
}
#if UNITY_2022_1_OR_NEWER
[Preserve]
internal static unsafe void RuntimeLog(byte* message, int logType, byte* fileName, int lineNumber)
{
Unity.Burst.LowLevel.BurstCompilerService.RuntimeLog((byte*) 0, (Unity.Burst.LowLevel.BurstCompilerService.BurstLogType)logType, message, fileName, lineNumber);
}
#endif
internal static void Initialize()
{
}
// Prevent BurstCompilerService.Log from being stripped, introduce PreserveAttribute to avoid
//requiring a unityengine using directive, il2cpp will see the attribute and know to not strip
//the Log method and its BurstCompilerService.Log dependency
internal class PreserveAttribute : System.Attribute {}
[Preserve]
internal static void PreventRequiredAttributeStrip()
{
new BurstDiscardAttribute();
// We also need to retain [Condition("UNITY_ASSERTION")] attributes in order to compile
// some assertion correctly (i.e. not compile them)
new ConditionalAttribute("HEJSA");
new JobProducerTypeAttribute(typeof(BurstRuntime));
}
[Preserve]
internal static unsafe void Log(byte* message, int logType, byte* fileName, int lineNumber)
{
Unity.Burst.LowLevel.BurstCompilerService.Log((byte*) 0, (Unity.Burst.LowLevel.BurstCompilerService.BurstLogType)logType, message, (byte*) 0, lineNumber);
}
#endif // !BURST_COMPILER_SHARED
/// <summary>
/// Return a pointer to read-only memory consisting of the literal UTF-8 bytes of a string constant.
/// </summary>
/// <param name="str">A string which must a string literal</param>
/// <param name="byteCount">Receives the number of UTF-8 encoded bytes the constant contains (excluding null terminator)</param>
/// <returns>A pointer to constant data representing the UTF-8 encoded bytes of the string literal, terminated with a null terminator</returns>
public unsafe static byte* GetUTF8LiteralPointer(string str, out int byteCount)
{
throw new NotImplementedException("This function only works from Burst");
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 26d2421d124d30c4b5dbee7057243ab2
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4592eab4973c370d8a7a7bb9cb4e4344
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 72b6a43cfa793c05b1a76ea3f3ba6367
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d549366794d73f618193482d7f40ae75
folderAsset: yes

View File

@@ -0,0 +1,72 @@
namespace Unity.Burst.CompilerServices
{
/// <summary>
/// Compile-time aliasing intrinsics.
/// </summary>
public static class Aliasing
{
/// <summary>
/// Will cause a compiler error in Burst-compiled code if a and b do not alias.
/// </summary>
/// <param name="a">A pointer to do aliasing checks on.</param>
/// <param name="b">A pointer to do aliasing checks on.</param>
public static unsafe void ExpectAliased(void* a, void* b) { }
/// <summary>
/// Will cause a compiler error in Burst-compiled code if a and b do not alias.
/// </summary>
/// <typeparam name="A">The type of a.</typeparam>
/// <typeparam name="B">The type of b.</typeparam>
/// <param name="a">A reference to do aliasing checks on.</param>
/// <param name="b">A reference to do aliasing checks on.</param>
public static void ExpectAliased<A, B>(in A a, in B b) where A : struct where B : struct { }
/// <summary>
/// Will cause a compiler error in Burst-compiled code if a and b do not alias.
/// </summary>
/// <typeparam name="B">The type of b.</typeparam>
/// <param name="a">A pointer to do aliasing checks on.</param>
/// <param name="b">A reference to do aliasing checks on.</param>
public static unsafe void ExpectAliased<B>(void* a, in B b) where B : struct { }
/// <summary>
/// Will cause a compiler error in Burst-compiled code if a and b do not alias.
/// </summary>
/// <typeparam name="A">The type of a.</typeparam>
/// <param name="a">A reference to do aliasing checks on.</param>
/// <param name="b">A pointer to do aliasing checks on.</param>
public static unsafe void ExpectAliased<A>(in A a, void* b) where A : struct { }
/// <summary>
/// Will cause a compiler error in Burst-compiled code if a and b can alias.
/// </summary>
/// <param name="a">A pointer to do aliasing checks on.</param>
/// <param name="b">A pointer to do aliasing checks on.</param>
public static unsafe void ExpectNotAliased(void* a, void* b) { }
/// <summary>
/// Will cause a compiler error in Burst-compiled code if a and b can alias.
/// </summary>
/// <typeparam name="A">The type of a.</typeparam>
/// <typeparam name="B">The type of b.</typeparam>
/// <param name="a">A reference to do aliasing checks on.</param>
/// <param name="b">A reference to do aliasing checks on.</param>
public static void ExpectNotAliased<A, B>(in A a, in B b) where A : struct where B : struct { }
/// <summary>
/// Will cause a compiler error in Burst-compiled code if a and b can alias.
/// </summary>
/// <typeparam name="B">The type of b.</typeparam>
/// <param name="a">A pointer to do aliasing checks on.</param>
/// <param name="b">A reference to do aliasing checks on.</param>
public static unsafe void ExpectNotAliased<B>(void* a, in B b) where B : struct { }
/// <summary>
/// Will cause a compiler error in Burst-compiled code if a and b can alias.
/// </summary>
/// <typeparam name="A">The type of a.</typeparam>
/// <param name="a">A reference to do aliasing checks on.</param>
/// <param name="b">A pointer to do aliasing checks on.</param>
public static unsafe void ExpectNotAliased<A>(in A a, void* b) where A : struct { }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 57a9f349ecdd3cd6b50a30954d4f50f3
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,31 @@
using System;
namespace Unity.Burst.CompilerServices
{
/// <summary>
/// Can be used to specify that a parameter or return has a range assumption.
/// Assumptions feed directly into the optimizer and allow better codegen.
///
/// Only usable on values of type scalar integer.
///
/// The range is a closed interval [min..max] - EG. the attributed value
/// is greater-than-or-equal-to min and less-than-or-equal-to max.
/// </summary>
[AttributeUsage(AttributeTargets.ReturnValue | AttributeTargets.Parameter)]
public class AssumeRangeAttribute : Attribute
{
/// <summary>
/// Assume that an integer is in the signed closed interval [min..max].
/// </summary>
/// <param name="min">The inclusive minimum value.</param>
/// <param name="max">The inclusive maximum value.</param>
public AssumeRangeAttribute(long min, long max) { }
/// <summary>
/// Assume that an integer is in the unsigned closed interval [min..max].
/// </summary>
/// <param name="min">The inclusive minimum value.</param>
/// <param name="max">The inclusive maximum value.</param>
public AssumeRangeAttribute(ulong min, ulong max) { }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 17055f9e032f36c6ae549103649199f4
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
namespace Unity.Burst.CompilerServices
{
/// <summary>
/// Compile-time queries intrinsics.
/// </summary>
public static class Constant
{
/// <summary>
/// Performs a compile-time check on whether the provided argument is known to be constant by Burst.
/// </summary>
/// <typeparam name="T">Type</typeparam>
/// <param name="t">The value to check whether it is constant.</param>
/// <returns>True if Burst knows at compile-time that it is a constant, false otherwise.</returns>
public static bool IsConstantExpression<T>(T t) where T : unmanaged => false;
/// <summary>
/// Performs a compile-time check on whether the provided argument is known to be constant by Burst.
/// </summary>
/// <param name="t">The value to check whether it is constant.</param>
/// <returns>True if Burst knows at compile-time that it is a constant, false otherwise.</returns>
public static unsafe bool IsConstantExpression(void* t) => false;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 425b1cb76be0397aae735d27918c5a76
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,28 @@
namespace Unity.Burst.CompilerServices
{
/// <summary>
/// Compile-time hint intrinsics.
/// </summary>
public static class Hint
{
/// <summary>
/// Hints to the compiler that the condition is likely to be true.
/// </summary>
/// <param name="condition">The boolean condition that is likely to be true.</param>
/// <returns>The condition.</returns>
public static bool Likely(bool condition) => condition;
/// <summary>
/// Hints to the compiler that the condition is unlikely to be true.
/// </summary>
/// <param name="condition">The boolean condition that is unlikely to be true.</param>
/// <returns>The condition.</returns>
public static bool Unlikely(bool condition) => condition;
/// <summary>
/// Hints to the compiler that the condition can be assumed to be true.
/// </summary>
/// <param name="condition">The boolean condition that can be assumed to be true.</param>
public static void Assume(bool condition) { }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b570e06d83103645837b57ee63c39049
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
using System;
namespace Unity.Burst.CompilerServices
{
/// <summary>
/// Can be used to specify that a warning produced by Burst for a given
/// method should be ignored.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class IgnoreWarningAttribute : Attribute
{
/// <summary>
/// Ignore a single warning produced by Burst.
/// </summary>
/// <param name="warning">The warning to ignore.</param>
public IgnoreWarningAttribute(int warning) { }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fae4cb13a004334fb1b9261d2a368cff
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,19 @@
namespace Unity.Burst.CompilerServices
{
#if UNITY_BURST_EXPERIMENTAL_LOOP_INTRINSICS
public static class Loop
{
/// <summary>
/// Must be called from inside a loop.
/// Will cause a compiler error in Burst-compiled code if the loop is not auto-vectorized.
/// </summary>
public static void ExpectVectorized() { }
/// <summary>
/// Must be called from inside a loop.
/// Will cause a compiler error in Burst-compiled code if the loop is auto-vectorized.
/// </summary>
public static void ExpectNotVectorized() { }
}
#endif
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 31e17c7531d63dcfa71f892d658bc44c
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,15 @@
using System;
namespace Unity.Burst.CompilerServices.Spmd
{
/// <summary>
/// Specifies that multiple calls to a method act as if they are
/// executing in a Single Program, Multiple Data (SPMD) paradigm.
/// </summary>
#if UNITY_BURST_EXPERIMENTAL_SPMD_ATTRIBUTE
[AttributeUsage(AttributeTargets.Method)]
public class SpmdAttribute : Attribute
{
}
#endif
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2d8f464f6c9033c89a0ee334f0aad30c
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,12 @@
using System;
namespace Unity.Burst.CompilerServices
{
/// <summary>
/// Skip zero-initialization of local variables.
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class SkipLocalsInitAttribute : Attribute
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5aea2c85eccf39d4807b4b09e1286046
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,225 @@
namespace Unity.Burst
{
/// <summary>
/// Specifies the possible diagnostic IDs.
/// </summary>
#if BURST_COMPILER_SHARED
public
#else
internal
#endif
enum DiagnosticId
{
// General
ERR_InternalCompilerErrorInBackend = 100,
ERR_InternalCompilerErrorInFunction = 101,
ERR_InternalCompilerErrorInInstruction = 102,
// ILBuilder
ERR_OnlyStaticMethodsAllowed = 1000,
ERR_UnableToAccessManagedMethod = 1001,
ERR_UnableToFindInterfaceMethod = 1002,
// ILCompiler
ERR_UnexpectedEmptyMethodBody = 1003,
ERR_ManagedArgumentsNotSupported = 1004,
// ERR_TryConstructionNotSupported = 1005, // not used anymore
ERR_CatchConstructionNotSupported = 1006,
ERR_CatchAndFilterConstructionNotSupported = 1007,
ERR_LdfldaWithFixedArrayExpected = 1008,
ERR_PointerExpected = 1009,
ERR_LoadingFieldFromManagedObjectNotSupported = 1010,
ERR_LoadingFieldWithManagedTypeNotSupported = 1011,
ERR_LoadingArgumentWithManagedTypeNotSupported = 1012,
ERR_CallingBurstDiscardMethodWithReturnValueNotSupported = 1015,
ERR_CallingManagedMethodNotSupported = 1016,
//ERR_BinaryPointerOperationNotSupported = 1017,
//ERR_AddingPointersWithNonPointerResultNotSupported = 1018,
ERR_InstructionUnboxNotSupported = 1019,
ERR_InstructionBoxNotSupported = 1020,
ERR_InstructionNewobjWithManagedTypeNotSupported = 1021,
ERR_AccessingManagedArrayNotSupported = 1022,
ERR_InstructionLdtokenFieldNotSupported = 1023,
ERR_InstructionLdtokenMethodNotSupported = 1024,
ERR_InstructionLdtokenTypeNotSupported = 1025,
ERR_InstructionLdtokenNotSupported = 1026,
ERR_InstructionLdvirtftnNotSupported = 1027,
ERR_InstructionNewarrNotSupported = 1028,
ERR_InstructionRethrowNotSupported = 1029,
ERR_InstructionCastclassNotSupported = 1030,
//ERR_InstructionIsinstNotSupported = 1031,
ERR_InstructionLdftnNotSupported = 1032,
ERR_InstructionLdstrNotSupported = 1033,
ERR_InstructionStsfldNotSupported = 1034,
ERR_InstructionEndfilterNotSupported = 1035,
ERR_InstructionEndfinallyNotSupported = 1036,
ERR_InstructionLeaveNotSupported = 1037,
ERR_InstructionNotSupported = 1038,
ERR_LoadingFromStaticFieldNotSupported = 1039,
ERR_LoadingFromNonReadonlyStaticFieldNotSupported = 1040,
ERR_LoadingFromManagedStaticFieldNotSupported = 1041,
ERR_LoadingFromManagedNonReadonlyStaticFieldNotSupported = 1042,
ERR_InstructionStfldToManagedObjectNotSupported = 1043,
ERR_InstructionLdlenNonConstantLengthNotSupported = 1044,
ERR_StructWithAutoLayoutNotSupported = 1045,
//ERR_StructWithPackNotSupported = 1046,
ERR_StructWithGenericParametersAndExplicitLayoutNotSupported = 1047,
ERR_StructSizeNotSupported = 1048,
ERR_StructZeroSizeNotSupported = 1049,
ERR_MarshalAsOnFieldNotSupported = 1050,
ERR_TypeNotSupported = 1051,
ERR_RequiredTypeModifierNotSupported = 1052,
ERR_ErrorWhileProcessingVariable = 1053,
// CecilExtensions
ERR_UnableToResolveType = 1054,
// ILFunctionReference
ERR_UnableToResolveMethod = 1055,
ERR_ConstructorNotSupported = 1056,
ERR_FunctionPointerMethodMissingBurstCompileAttribute = 1057,
ERR_FunctionPointerTypeMissingBurstCompileAttribute = 1058,
ERR_FunctionPointerMethodAndTypeMissingBurstCompileAttribute = 1059,
INF_FunctionPointerMethodAndTypeMissingMonoPInvokeCallbackAttribute = 10590,
// ILVisitor
// ERR_EntryPointFunctionCannotBeCalledInternally = 1060, // no longer used
// ExternalFunctionParameterChecks
ERR_MarshalAsOnParameterNotSupported = 1061,
ERR_MarshalAsOnReturnTypeNotSupported = 1062,
ERR_TypeNotBlittableForFunctionPointer = 1063,
ERR_StructByValueNotSupported = 1064,
ERR_StructsWithNonUnicodeCharsNotSupported = 1066,
ERR_VectorsByValueNotSupported = 1067,
// JitCompiler
ERR_MissingExternBindings = 1068,
// More ExternalFunctionParameterChecks
ERR_MarshalAsNativeTypeOnReturnTypeNotSupported = 1069,
// AssertProcessor
ERR_AssertTypeNotSupported = 1071,
// ReadOnlyProcessor
ERR_StoringToReadOnlyFieldNotAllowed = 1072,
ERR_StoringToFieldInReadOnlyParameterNotAllowed = 1073,
ERR_StoringToReadOnlyParameterNotAllowed = 1074,
// TypeManagerProcessor
ERR_TypeManagerStaticFieldNotCompatible = 1075,
ERR_UnableToFindTypeIndexForTypeManagerType = 1076,
ERR_UnableToFindFieldForTypeManager = 1077,
// Deprecated NoAliasAnalyzer
// WRN_DisablingNoaliasUnsupportedLdobjImplicitNativeContainer = 1078,
// WRN_DisablingNoaliasLoadingDirectlyFromFieldOfNativeArray = 1079,
// WRN_DisablingNoaliasWritingDirectlyToFieldOfNativeArray = 1080,
// WRN_DisablingNoaliasStoringImplicitNativeContainerToField = 1081,
// WRN_DisablingNoaliasStoringImplicitNativeContainerToLocalVariable = 1082,
// WRN_DisablingNoaliasStoringImplicitNativeContainerToPointer = 1083,
// WRN_DisablingNoaliasCannotLoadNativeContainerAsBothArgumentAndField = 1084,
// WRN_DisablingNoaliasSameArgumentPath = 1085,
// WRN_DisablingNoaliasCannotPassMultipleNativeContainersConcurrently = 1086,
// WRN_DisablingNoaliasUnsupportedNativeArrayUnsafeUtilityMethod = 1087,
// WRN_DisablingNoaliasUnsupportedNativeArrayMethod = 1088,
// WRN_DisablingNoaliasUnsupportedThisArgument = 1089,
// StaticFieldAccessTransform
ERR_CircularStaticConstructorUsage = 1090,
ERR_ExternalInternalCallsInStaticConstructorsNotSupported = 1091,
// AotCompiler
ERR_PlatformNotSupported = 1092,
ERR_InitModuleVerificationError = 1093,
// NativeCompiler
ERR_ModuleVerificationError = 1094,
// TypeManagerProcessor
ERR_UnableToFindTypeRequiredForTypeManager = 1095,
// ILBuilder
ERR_UnexpectedIntegerTypesForBinaryOperation = 1096,
ERR_BinaryOperationNotSupported = 1097,
ERR_CalliWithThisNotSupported = 1098,
ERR_CalliNonCCallingConventionNotSupported = 1099,
ERR_StringLiteralTooBig = 1100,
ERR_LdftnNonCCallingConventionNotSupported = 1101,
ERR_UnableToCallMethodOnInterfaceObject = 1102,
// CheckIntrinsicUsageTransform
ERR_UnsupportedCpuDependentBranch = 1199,
ERR_InstructionTargetCpuFeatureNotAllowedInThisBlock = 1200,
// AssumeRange
ERR_AssumeRangeTypeMustBeInteger = 1201,
ERR_AssumeRangeTypeMustBeSameSign = 1202,
// LdfldaTransform
ERR_UnsupportedSpillTransform = 1300,
ERR_UnsupportedSpillTransformTooManyUsers = 1301,
// Intrinsics
ERR_MethodNotSupported = 1302,
ERR_VectorsLoadFieldIsAddress = 1303,
ERR_ConstantExpressionRequired = 1304,
// UBAA
ERR_PointerArgumentsUnexpectedAliasing = 1310,
// Loop intrinsics
ERR_LoopIntrinsicMustBeCalledInsideLoop = 1320,
ERR_LoopUnexpectedAutoVectorization = 1321,
WRN_LoopIntrinsicCalledButLoopOptimizedAway = 1322,
// AssertProcessor
ERR_AssertArgTypesDiffer = 1330,
// StringUsageTransform
ERR_StringInternalCompilerFixedStringTooManyUsers = 1340,
ERR_StringInvalidFormatMissingClosingBrace = 1341,
ERR_StringInvalidIntegerForArgumentIndex = 1342,
ERR_StringInvalidFormatForArgument = 1343,
ERR_StringArgumentIndexOutOfRange = 1344,
ERR_StringInvalidArgumentType = 1345,
ERR_DebugLogNotSupported = 1346,
ERR_StringInvalidNonLiteralFormat = 1347,
ERR_StringInvalidStringFormatMethod = 1348,
ERR_StringInvalidArgument = 1349,
ERR_StringArrayInvalidArrayCreation = 1350,
ERR_StringArrayInvalidArraySize = 1351,
ERR_StringArrayInvalidControlFlow = 1352,
ERR_StringArrayInvalidArrayIndex = 1353,
ERR_StringArrayInvalidArrayIndexOutOfRange = 1354,
ERR_UnmanagedStringMethodMissing = 1355,
ERR_UnmanagedStringMethodInvalid = 1356,
// Static constructor
ERR_ManagedStaticConstructor = 1360,
ERR_StaticConstantArrayInStaticConstructor = 1361,
// Safety check warning
WRN_ExceptionThrownInNonSafetyCheckGuardedFunction = 1370,
// Discarded method warning
WRN_ACallToMethodHasBeenDiscarded = 1371,
// Accessing a nested managed array is not supported
ERR_AccessingNestedManagedArrayNotSupported = 1380,
// Loading from a non-pointer / non-reference is not supported
ERR_LdobjFromANonPointerNonReference = 1381,
ERR_StringLiteralRequired = 1382,
ERR_MultiDimensionalArrayUnsupported = 1383,
ERR_NonBlittableAndNonManagedSequentialStructNotSupported = 1384,
ERR_VarArgFunctionNotSupported = 1385,
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6dc46e7a016d3761a4586c439a8d9021
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c433e85ffb033bc99961d95aba84d010
folderAsset: yes

View File

@@ -0,0 +1,78 @@
#if UNITY_EDITOR
using System;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace Unity.Burst.Editor
{
/// <summary>
/// Allow disabling of the Burst compiler for specific assemblies.
/// ProjectSettings/Burst_DisableAssembliesForEditorCompilation.json
/// ProjectSettings/Burst_DisableAssembliesForPlayerCompilation.json
/// ProjectSettings/Burst_DisableAssembliesForPlayerCompilation_{platform}.json // if exists taken in preference to the one immediately above
/// </summary>
internal static class BurstAssemblyDisable
{
public enum DisableType
{
Editor,
Player
}
private static string GetPath(DisableType type, string platformIdentifier)
{
if (DisableType.Editor == type)
{
return "ProjectSettings/Burst_DisableAssembliesForEditorCompilation.json";
}
var platformSpecicPath = $"ProjectSettings/Burst_DisableAssembliesForPlayerCompilation_{platformIdentifier}.json";
if (File.Exists(platformSpecicPath))
{
return platformSpecicPath;
}
return "ProjectSettings/Burst_DisableAssembliesForPlayerCompilation.json";
}
public static string[] GetDisabledAssemblies(DisableType type, string platformIdentifier)
{
var pathForSettings = GetPath(type, platformIdentifier);
if (!File.Exists(pathForSettings))
{
return Array.Empty<string>();
}
var settings = new BackwardsCompatWrapper();
JsonUtility.FromJsonOverwrite(File.ReadAllText(pathForSettings),settings);
if (settings == null || settings.MonoBehaviour == null || settings.MonoBehaviour.DisabledAssemblies == null)
{
return Array.Empty<string>();
}
return settings.MonoBehaviour.DisabledAssemblies;
}
}
/// <summary>
/// Settings file -
///
///{
/// "MonoBehaviour": {
/// "DisabledAssemblies":
/// [
/// "Example.Assembly"
/// ]
/// }
///}
/// </summary>
[Serializable]
class BackwardsCompatWrapper
{
public BurstDisableSettings MonoBehaviour;
}
[Serializable]
class BurstDisableSettings
{
public string[] DisabledAssemblies;
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 24e5242d7f213ce49a52eefb5d544d24
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,183 @@
#if UNITY_EDITOR
using System;
using System.Diagnostics;
using System.Reflection;
using System.Text;
namespace Unity.Burst.Editor
{
[DebuggerDisplay("{GetDisplayName(),nq}")]
internal class BurstCompileTarget
{
public BurstCompileTarget(MethodInfo method, Type jobType, Type interfaceType, bool isStaticMethod)
{
Method = method ?? throw new ArgumentNullException(nameof(method));
JobType = jobType ?? throw new ArgumentNullException(nameof(jobType));
JobInterfaceType = interfaceType; // can be null
// This is important to clone the options as we don't want to modify the global instance
Options = BurstCompiler.Options.Clone();
Options.EnableBurstCompilation = true;
// Enable safety checks by default to match inspector default behavior
Options.EnableBurstSafetyChecks = true;
TargetCpu = BurstTargetCpu.Auto;
// The BurstCompilerAttribute can be either on the type or on the method
IsStaticMethod = isStaticMethod;
}
/// <summary>
/// <c>true</c> if the <see cref="Method"/> is directly tagged with a [BurstCompile] attribute
/// </summary>
public readonly bool IsStaticMethod;
/// <summary>
/// The Execute method of the target's producer type.
/// </summary>
public readonly MethodInfo Method;
/// <summary>
/// The type of the actual job (i.e. BoidsSimulationJob).
/// </summary>
public readonly Type JobType;
/// <summary>
/// The interface of the job (IJob, IJobParallelFor...)
/// </summary>
public readonly Type JobInterfaceType;
/// <summary>
/// The default compiler options
/// </summary>
public readonly BurstCompilerOptions Options;
public BurstTargetCpu TargetCpu { get; set; }
/// <summary>
/// Set to true if burst compilation is actually requested via proper `[BurstCompile]` attribute:
/// - On the job if it is a job only
/// - On the method and parent class it if is a static method
/// </summary>
public bool HasRequiredBurstCompileAttributes => BurstCompilerOptions.HasBurstCompileAttribute(JobType) && (!IsStaticMethod || BurstCompilerOptions.HasBurstCompileAttribute(Method));
/// <summary>
/// Generated raw disassembly (IR, IL, ASM...), or null if disassembly failed (only valid for the current TargetCpu)
/// </summary>
public string RawDisassembly;
/// <summary>
/// Formatted disassembly for the associated <see cref="RawDisassembly"/>, currently only valid for <see cref="Unity.Burst.Editor.DisassemblyKind.Asm"/>
/// </summary>
public string FormattedDisassembly;
public DisassemblyKind DisassemblyKind;
public bool IsDarkMode { get; set; }
public bool IsBurstError { get; set; }
public bool IsLoading = false;
public bool JustLoaded = false;
public string GetDisplayName()
{
var displayName = IsStaticMethod ? Pretty(Method) : $"{Pretty(JobType)} - ({Pretty(JobInterfaceType)})";
// Remove the '<>c__DisplayClass_' part of the name - this is only added for C# Entities.ForEach jobs to trick the C# debugging tools into
// treating them like lambdas. This is removed wherever possible from user facing tools (like the Unity profiler), so we should do the same.
return displayName.Replace("<>c__DisplayClass_", "");
}
private static string Pretty(MethodInfo method)
{
var builder = new StringBuilder();
builder.Append(Pretty(method.DeclaringType));
builder.Append(".");
builder.Append(method.Name);
builder.Append("(");
var parameters = method.GetParameters();
for (var i = 0; i < parameters.Length; i++)
{
var param = parameters[i];
if (i > 0) builder.Append(", ");
builder.Append(Pretty(param.ParameterType));
}
builder.Append(")");
return builder.ToString();
}
internal static string Pretty(Type type)
{
if (type == typeof(bool))
{
return "bool";
}
if (type == typeof(int))
{
return "int";
}
if (type == typeof(long))
{
return "long";
}
if (type == typeof(uint))
{
return "uint";
}
if (type == typeof(ulong))
{
return "ulong";
}
if (type == typeof(short))
{
return "short";
}
if (type == typeof(ushort))
{
return "ushort";
}
if (type == typeof(byte))
{
return "byte";
}
if (type == typeof(sbyte))
{
return "sbyte";
}
if (type == typeof(float))
{
return "float";
}
if (type == typeof(double))
{
return "double";
}
if (type == typeof(string))
{
return "string";
}
if (type == typeof(object))
{
return "object";
}
if (type == typeof(char))
{
return "char";
}
// When displaying job interface type, display the interface name of Unity.Jobs namespace
var typeName = type.IsInterface && type.Name.StartsWith("IJob") ? type.Name : type.ToString();
return typeName.Replace("+", ".");
}
}
internal enum DisassemblyKind
{
Asm = 0,
IL = 1,
UnoptimizedIR = 2,
OptimizedIR = 3,
IRPassAnalysis = 4
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8e0e4e7742393f00808df3e4508a7327
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,124 @@
#if UNITY_EDITOR
using System.Diagnostics;
using UnityEditor;
namespace Unity.Burst.Editor
{
/// <summary>
/// Responsible to synchronize <see cref="BurstCompiler.Options"/> with the menu
/// </summary>
internal static class BurstEditorOptions
{
// Properties stored in SessionState (survive between domain reloads, but stays alive only during the life of the editor)
private const string EnableBurstSafetyChecksText = "BurstSafetyChecks";
// Properties stored in EditorPrefs (survive between editor restart)
private const string EnableBurstCompilationText = "BurstCompilation";
private const string EnableBurstTimingsText = "BurstShowTimings";
private const string EnableBurstCompileSynchronouslyText = "BurstCompileSynchronously";
private const string EnableBurstDebugText = "BurstDebug";
private const string ForceEnableBurstSafetyChecksText = "BurstForceSafetyChecks";
/// <summary>
/// <c>true</c> if the menu options are synchronized with <see cref="BurstCompiler.Options"/>
/// </summary>
private static bool _isSynchronized;
public static void EnsureSynchronized()
{
GetGlobalOptions();
}
public static bool EnableBurstCompilation
{
get => GetGlobalOptions().EnableBurstCompilation;
set
{
var enabled = GetGlobalOptions().EnableBurstCompilation;
GetGlobalOptions().EnableBurstCompilation = value;
if (!enabled && value)
{
// Must be called AFTER we actually enable compilation
BurstCompiler.TriggerUnsafeStaticMethodRecompilation();
}
}
}
public static bool EnableBurstSafetyChecks
{
get => GetGlobalOptions().EnableBurstSafetyChecks;
set => GetGlobalOptions().EnableBurstSafetyChecks = value;
}
public static bool EnableBurstCompileSynchronously
{
get => GetGlobalOptions().EnableBurstCompileSynchronously;
set => GetGlobalOptions().EnableBurstCompileSynchronously = value;
}
public static bool EnableBurstTimings
{
get => GetGlobalOptions().EnableBurstTimings;
set => GetGlobalOptions().EnableBurstTimings = value;
}
public static bool EnableBurstDebug
{
get => GetGlobalOptions().EnableBurstDebug;
set => GetGlobalOptions().EnableBurstDebug = value;
}
public static bool ForceEnableBurstSafetyChecks
{
get => GetGlobalOptions().ForceEnableBurstSafetyChecks;
set => GetGlobalOptions().ForceEnableBurstSafetyChecks = value;
}
private static BurstCompilerOptions GetGlobalOptions()
{
var global = BurstCompiler.Options;
// If options are not synchronize with our global instance, setup the sync
if (!_isSynchronized)
{
global.IsInitializing = true;
try
{
// Setup the synchronization
global.EnableBurstCompilation = EditorPrefs.GetBool(EnableBurstCompilationText, true);
global.EnableBurstCompileSynchronously = EditorPrefs.GetBool(EnableBurstCompileSynchronouslyText, false);
global.EnableBurstTimings = EditorPrefs.GetBool(EnableBurstTimingsText, false);
global.EnableBurstDebug = EditorPrefs.GetBool(EnableBurstDebugText, false);
global.ForceEnableBurstSafetyChecks = EditorPrefs.GetBool(ForceEnableBurstSafetyChecksText, false);
// Session only properties
global.EnableBurstSafetyChecks = SessionState.GetBool(EnableBurstSafetyChecksText, true);
}
finally
{
global.IsInitializing = false;
}
global.OptionsChanged += GlobalOnOptionsChanged;
_isSynchronized = true;
}
return global;
}
private static void GlobalOnOptionsChanged()
{
var global = BurstCompiler.Options;
// We are not optimizing anything here, so whenever one option is set, we reset all of them
EditorPrefs.SetBool(EnableBurstCompilationText, global.EnableBurstCompilation);
EditorPrefs.SetBool(EnableBurstCompileSynchronouslyText, global.EnableBurstCompileSynchronously);
EditorPrefs.SetBool(EnableBurstTimingsText, global.EnableBurstTimings);
EditorPrefs.SetBool(EnableBurstDebugText, global.EnableBurstDebug);
EditorPrefs.SetBool(ForceEnableBurstSafetyChecksText, global.ForceEnableBurstSafetyChecks);
// Session only properties
SessionState.SetBool(EnableBurstSafetyChecksText, global.EnableBurstSafetyChecks);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d81d96b8ea1936359196f069c6e225d8
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,770 @@
#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Unity.Burst.LowLevel;
using Unity.Profiling;
using Unity.Profiling.LowLevel;
using Unity.Profiling.LowLevel.Unsafe;
using UnityEditor;
using UnityEditor.Compilation;
using UnityEditor.Scripting.ScriptCompilation;
using UnityEngine;
namespace Unity.Burst.Editor
{
/// <summary>
/// Main entry point for initializing the burst compiler service for both JIT and AOT
/// </summary>
[InitializeOnLoad]
internal class BurstLoader
{
private const int BURST_PROTOCOL_VERSION = 1;
// Cache the delegate to make sure it doesn't get collected.
private static readonly BurstCompilerService.ExtractCompilerFlags TryGetOptionsFromMemberDelegate = TryGetOptionsFromMember;
/// <summary>
/// Gets the location to the runtime path of burst.
/// </summary>
public static string RuntimePath { get; private set; }
public static BclConfiguration BclConfiguration { get; private set; }
public static bool IsDebugging { get; private set; }
public static bool SafeShutdown { get; private set; }
public static int ProtocolVersion { get; private set; }
private static void VersionUpdateCheck()
{
var seek = "com.unity.burst@";
var first = RuntimePath.LastIndexOf(seek);
var last = RuntimePath.LastIndexOf(".Runtime");
string version;
if (first == -1 || last == -1 || last <= first)
{
version = "Unknown";
}
else
{
first += seek.Length;
last -= 1;
version = RuntimePath.Substring(first, last - first);
}
var result = BurstCompiler.VersionNotify(version);
// result will be empty if we are shutting down, and thus we shouldn't popup a dialog
if (!String.IsNullOrEmpty(result) && result != version)
{
if (IsDebugging)
{
UnityEngine.Debug.LogWarning($"[com.unity.burst] - '{result}' != '{version}'");
}
OnVersionChangeDetected();
}
}
private static bool UnityBurstRuntimePathOverwritten(out string path)
{
path = Environment.GetEnvironmentVariable("UNITY_BURST_RUNTIME_PATH");
return Directory.Exists(path);
}
private static void OnVersionChangeDetected()
{
// Write marker file to tell Burst to delete the cache at next startup.
try
{
File.Create(Path.Combine(BurstCompilerOptions.DefaultCacheFolder, BurstCompilerOptions.DeleteCacheMarkerFileName)).Dispose();
}
catch (IOException)
{
// In the unlikely scenario that two processes are creating this marker file at the same time,
// and one of them fails, do nothing because the other one has hopefully succeeded.
}
// Skip checking if we are using an explicit runtime path.
if (!UnityBurstRuntimePathOverwritten(out var _))
{
EditorUtility.DisplayDialog("Burst Package Update Detected", "The version of Burst used by your project has changed. Please restart the Editor to continue.", "OK");
BurstCompiler.Shutdown();
}
}
private static CompilationTaskReason _currentBuildKind;
static BurstLoader()
{
if (BurstCompilerOptions.ForceDisableBurstCompilation)
{
if (!BurstCompilerOptions.IsSecondaryUnityProcess)
{
UnityEngine.Debug.LogWarning("[com.unity.burst] Burst is disabled entirely from the command line or environment variable");
}
return;
}
// This can be setup to get more diagnostics
var debuggingStr = Environment.GetEnvironmentVariable("UNITY_BURST_DEBUG");
IsDebugging = debuggingStr != null && int.TryParse(debuggingStr, out var debugLevel) && debugLevel > 0;
if (IsDebugging)
{
UnityEngine.Debug.LogWarning("[com.unity.burst] Extra debugging is turned on.");
}
// Try to load the runtime through an environment variable
var isRuntimePathOverwritten = UnityBurstRuntimePathOverwritten(out var path);
if (!isRuntimePathOverwritten)
{
// Otherwise try to load it from the package itself
#if UNITY_2021_3_OR_NEWER
path = FileUtil.GetPhysicalPath("Packages/com.unity.burst/.Runtime");
#else
path = Path.GetFullPath("Packages/com.unity.burst/.Runtime");
#endif
}
RuntimePath = path;
BclConfiguration = GetBclConfiguration(path, isRuntimePathOverwritten);
if (IsDebugging)
{
UnityEngine.Debug.LogWarning($"[com.unity.burst] Runtime directory set to {RuntimePath}");
}
BurstCompilerService.Initialize(RuntimePath, TryGetOptionsFromMemberDelegate);
ProtocolVersion = BurstCompiler.RequestSetProtocolVersion(BURST_PROTOCOL_VERSION);
BurstCompiler.Initialize(GetAssemblyFolders(),BurstAssemblyDisable.GetDisabledAssemblies(BurstAssemblyDisable.DisableType.Editor, ""));
// It's important that this call comes *after* BurstCompilerService.Initialize,
// otherwise any calls from within EnsureSynchronized to BurstCompilerService,
// such as BurstCompiler.Disable(), will silently fail.
BurstEditorOptions.EnsureSynchronized();
EditorApplication.quitting += OnEditorApplicationQuitting;
CompilationPipeline.compilationStarted += OnCompilationStarted;
CompilationPipeline.compilationFinished += OnCompilationFinished;
// We use this internal event because it's the only way to get access to the ScriptAssembly.HasCompileErrors,
// which tells us whether C# compilation succeeded or failed for this assembly.
EditorCompilationInterface.Instance.assemblyCompilationFinished += OnAssemblyCompilationFinished;
#if UNITY_2022_2_OR_NEWER
CompilationPipeline.assemblyCompilationNotRequired += OnAssemblyCompilationNotRequired;
#endif
EditorApplication.playModeStateChanged += EditorApplicationOnPlayModeStateChanged;
AppDomain.CurrentDomain.DomainUnload += OnDomainUnload;
SafeShutdown = false;
UnityEditor.PackageManager.Events.registeringPackages += PackageRegistrationEvent;
SafeShutdown = BurstCompiler.IsApiAvailable("SafeShutdown");
if (!SafeShutdown)
{
VersionUpdateCheck();
}
// Notify the compiler about a domain reload
if (IsDebugging)
{
UnityEngine.Debug.Log("Burst - Domain Reload");
}
BurstCompiler.OnProgress += OnProgress;
BurstCompiler.EagerCompilationLoggingEnabled = true;
// Make sure BurstRuntime is initialized. This needs to happen before BurstCompiler.DomainReload,
// because that can cause calls to BurstRuntime.Log.
BurstRuntime.Initialize();
// Notify the JitCompilerService about a domain reload
BurstCompiler.SetDefaultOptions();
BurstCompiler.DomainReload();
BurstCompiler.OnProfileBegin += OnProfileBegin;
BurstCompiler.OnProfileEnd += OnProfileEnd;
BurstCompiler.SetProfilerCallbacks();
BurstCompiler.InitialiseDebuggerHooks();
}
private static bool _isQuitting;
private static void OnEditorApplicationQuitting()
{
_isQuitting = true;
}
public static Action OnBurstShutdown;
private static void PackageRegistrationEvent(UnityEditor.PackageManager.PackageRegistrationEventArgs obj)
{
bool requireCleanup = false;
if (SafeShutdown)
{
foreach (var changed in obj.changedFrom)
{
if (changed.name.Contains("com.unity.burst"))
{
requireCleanup = true;
break;
}
}
}
foreach (var removed in obj.removed)
{
if (removed.name.Contains("com.unity.burst"))
{
requireCleanup = true;
}
}
if (requireCleanup)
{
OnBurstShutdown?.Invoke();
if (!SafeShutdown)
{
EditorUtility.DisplayDialog("Burst Package Has Been Removed", "Please restart the Editor to continue.", "OK");
}
BurstCompiler.Shutdown();
}
}
private static BclConfiguration GetBclConfiguration(string runtimePath, bool isRuntimePathOverwritten)
{
string bclFolderPath;
if (isRuntimePathOverwritten)
{
return new BclConfiguration
{
FolderPath = runtimePath,
ExecutablePath = Path.Combine(runtimePath, "bcl.exe"),
IsExecutableNative = false,
};
}
else
{
bclFolderPath = Path.Combine(runtimePath, "bcl", GetBclPlatformFolderName());
if (Directory.Exists(bclFolderPath))
{
var bclFileName = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? "bcl.exe"
: "bcl";
return new BclConfiguration
{
FolderPath = bclFolderPath,
ExecutablePath = Path.Combine(bclFolderPath, bclFileName),
IsExecutableNative = true,
};
}
return new BclConfiguration
{
FolderPath = runtimePath,
ExecutablePath = Path.Combine(runtimePath, "bcl.exe"),
IsExecutableNative = false,
};
}
}
private static string GetBclPlatformFolderName()
{
var hostPlatform = Application.platform;
var hostArchitecture = RuntimeInformation.OSArchitecture;
switch (hostPlatform)
{
case RuntimePlatform.WindowsEditor:
return "win-x64";
case RuntimePlatform.OSXEditor when hostArchitecture == Architecture.X64:
return "osx-x64";
case RuntimePlatform.OSXEditor when hostArchitecture == Architecture.Arm64:
return "osx-arm64";
case RuntimePlatform.LinuxEditor:
return "linux-x64";
default:
throw new InvalidOperationException($"Current OS platform {hostPlatform} and architecture {hostArchitecture} combination is not supported");
}
}
// Don't initialize to 0 because that could be a valid progress ID.
private static int BurstProgressId = -1;
// If this enum changes, update the benchmarks tool accordingly as we rely on integer value related to this enum
internal enum BurstEagerCompilationStatus
{
NotScheduled,
Scheduled,
Completed
}
// For the time being, this field is only read through reflection
internal static BurstEagerCompilationStatus EagerCompilationStatus;
private static void OnProgress(int current, int total)
{
if (current == total)
{
EagerCompilationStatus = BurstEagerCompilationStatus.Completed;
}
// OnProgress is called from a background thread,
// but we need to update the progress UI on the main thread.
EditorApplication.CallDelayed(() =>
{
if (current == total)
{
// We've finished - remove progress bar.
if (Progress.Exists(BurstProgressId))
{
Progress.Remove(BurstProgressId);
BurstProgressId = -1;
}
}
else
{
// Do we need to create the progress bar?
if (!Progress.Exists(BurstProgressId))
{
BurstProgressId = Progress.Start(
"Burst",
"Compiling...",
Progress.Options.Unmanaged);
}
Progress.Report(
BurstProgressId,
current / (float)total,
$"Compiled {current} / {total} libraries");
}
});
}
[ThreadStatic]
private static Dictionary<string, IntPtr> ProfilerMarkers;
private static unsafe void OnProfileBegin(string markerName, string metadataName, string metadataValue)
{
if (ProfilerMarkers == null)
{
// Initialize thread-static dictionary.
ProfilerMarkers = new Dictionary<string, IntPtr>();
}
if (!ProfilerMarkers.TryGetValue(markerName, out var markerPtr))
{
ProfilerMarkers.Add(markerName, markerPtr = ProfilerUnsafeUtility.CreateMarker(
markerName,
ProfilerUnsafeUtility.CategoryScripts,
MarkerFlags.Script,
metadataName != null ? 1 : 0));
// metadataName is assumed to be consistent for a given markerName.
if (metadataName != null)
{
ProfilerUnsafeUtility.SetMarkerMetadata(
markerPtr,
0,
metadataName,
(byte)ProfilerMarkerDataType.String16,
(byte)ProfilerMarkerDataUnit.Undefined);
}
}
if (metadataName != null && metadataValue != null)
{
fixed (char* methodNamePtr = metadataValue)
{
var metadata = new ProfilerMarkerData
{
Type = (byte)ProfilerMarkerDataType.String16,
Size = ((uint)metadataValue.Length + 1) * 2,
Ptr = methodNamePtr
};
ProfilerUnsafeUtility.BeginSampleWithMetadata(markerPtr, 1, &metadata);
}
}
else
{
ProfilerUnsafeUtility.BeginSample(markerPtr);
}
}
private static void OnProfileEnd(string markerName)
{
if (ProfilerMarkers == null)
{
// If we got here it means we had a domain reload between when we called profile begin and
// now profile end, and so we need to bail out.
return;
}
if (!ProfilerMarkers.TryGetValue(markerName, out var markerPtr))
{
return;
}
ProfilerUnsafeUtility.EndSample(markerPtr);
}
private static void EditorApplicationOnPlayModeStateChanged(PlayModeStateChange state)
{
if (IsDebugging)
{
UnityEngine.Debug.Log($"Burst - Change of Editor State: {state}");
}
switch (state)
{
case PlayModeStateChange.ExitingPlayMode:
// Cleanup any loaded burst natives so users have a clean point to update the libraries.
BurstCompiler.UnloadAdditionalLibraries();
break;
}
}
enum CompilationTaskReason
{
IsForEditor, // Compilation should proceed as its for an editor build
IsForPlayer, // Skip this compilation
IsForPreviousScriptingMode, // We are about to enter a domain reload, don't start any new compilations
IsForAssemblyBuilder, // Request is coming from an 'AssemblyBuilder' and should be skipped as not supported
}
static CompilationTaskReason CurrentCompilationTaskShouldStart()
{
try
{
if (BurstCompiler.WasScriptDebugInfoEnabledAtDomainReload != UnityEditor.Compilation.CompilationPipeline.IsScriptDebugInfoEnabled())
{
// If the scripting compilation mode has changed since we last had our domain reloaded, then we ignore all requests, and act as if
//loading for the first time. This is to avoid having compilations kick off right before a Shutdown triggered by domain reload, that
//would cause the a significant stall as we had to wait for those compilations to finish, thus blocking the main thread.
return CompilationTaskReason.IsForPreviousScriptingMode;
}
var inst = EditorCompilationInterface.Instance;
#if UNITY_2021_1_OR_NEWER
var editorCompilationType = inst.GetType();
var activeBeeBuildField = editorCompilationType.GetField("_currentBeeScriptCompilationState", BindingFlags.Instance | BindingFlags.NonPublic);
if (activeBeeBuildField == null)
{
activeBeeBuildField = editorCompilationType.GetField("activeBeeBuild", BindingFlags.Instance | BindingFlags.NonPublic);
}
var activeBeeBuild = activeBeeBuildField.GetValue(inst);
// If a user is doing an `AssemblyBuilder` compilation, we do not support that in Burst.
// This seems to manifest as a null `activeBeeBuild`, so we bail here if that happens.
if (activeBeeBuild == null)
{
return CompilationTaskReason.IsForAssemblyBuilder;
}
var settings = activeBeeBuild.GetType().GetProperty("settings", BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance).GetValue(activeBeeBuild);
var opt = (EditorScriptCompilationOptions)settings.GetType().GetProperty("CompilationOptions").GetValue(settings);
#else
var task = inst.GetType()
.GetField("compilationTask", BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(inst);
// If a user is doing an `AssemblyBuilder` compilation, we do not support that in Burst.
// This seems to manifest as a null `task`, so we bail here if that happens.
if (task == null)
{
return CompilationTaskReason.IsForAssemblyBuilder;
}
var opt = (EditorScriptCompilationOptions)task.GetType()
.GetField("options", BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(task);
#endif
#if UNITY_2022_2_OR_NEWER
if ((opt & EditorScriptCompilationOptions.BuildingSkipCompile) != 0)
{
return CompilationTaskReason.IsForPlayer;
}
#endif
if ((opt & EditorScriptCompilationOptions.BuildingForEditor) != 0)
{
return CompilationTaskReason.IsForEditor;
}
return CompilationTaskReason.IsForPlayer;
}
catch (Exception ex)
{
UnityEngine.Debug.LogWarning("Burst - Unknown private compilation pipeline API\nAssuming editor build\n" + ex.ToString());
return CompilationTaskReason.IsForEditor;
}
}
private static void OnCompilationStarted(object value)
{
_currentBuildKind = CurrentCompilationTaskShouldStart();
if (_currentBuildKind != CompilationTaskReason.IsForEditor)
{
if (IsDebugging)
{
UnityEngine.Debug.Log($"{DateTime.UtcNow} Burst - not handling '{value}' because '{_currentBuildKind}'");
}
return;
}
if (IsDebugging)
{
UnityEngine.Debug.Log($"{DateTime.UtcNow} Burst - compilation started for '{value}'");
}
BurstCompiler.NotifyCompilationStarted(GetAssemblyFolders(),
BurstAssemblyDisable.GetDisabledAssemblies(BurstAssemblyDisable.DisableType.Editor,"") );
}
private static string[] GetAssemblyFolders()
{
var assemblyFolders = new HashSet<string>();
// First, we get the path to Mono system libraries. This will be something like
// <EditorPath>/Data/MonoBleedingEdge/lib/mono/unityjit-win32
//
// You might think we could use MonoLibraryHelpers.GetSystemReferenceDirectories
// here, but we can't, because that returns the _reference assembly_ directories,
// not the actual implementation assembly directory.
var systemLibraryDirectory = Path.GetDirectoryName(typeof(object).Assembly.Location);
assemblyFolders.Add(systemLibraryDirectory);
// Also add the Facades directory, since that contains netstandard. Without this,
// we'll potentially resolve the "wrong" netstandard from a dotnet compiler host.
assemblyFolders.Add(Path.Combine(systemLibraryDirectory, "Facades"));
// Now add the default assembly search paths.
// This will include
// - Unity dlls in <EditorPath>/Data/Managed and <EditorPath>/Data/Managed/UnityEngine
// - Platform support dlls e.g. <EditorPath>/Data/PlaybackEngines/WindowsStandaloneSupport
// - Package paths. These are interesting because they are "virtual" paths, of the form
// Packages/<MyPackageName>. They need to be resolved to physical paths.
// - Library/ScriptAssemblies. This needs to be resolved to the full path.
var defaultAssemblySearchPaths = AssemblyHelper.GetDefaultAssemblySearchPaths();
#if UNITY_2021_3_OR_NEWER
foreach (var searchPath in defaultAssemblySearchPaths)
{
var resolvedPath = FileUtil.PathToAbsolutePath(searchPath);
if (!string.IsNullOrEmpty(resolvedPath))
{
assemblyFolders.Add(resolvedPath);
}
}
#else
var packagesLookup = GetPackagesLookup();
foreach (var searchPath in defaultAssemblySearchPaths)
{
if (TryResolvePath(searchPath, packagesLookup, out var resolvedPath))
{
assemblyFolders.Add(resolvedPath);
}
}
#endif
if (IsDebugging)
{
UnityEngine.Debug.Log($"{DateTime.UtcNow} Burst - AssemblyFolders : \n{string.Join("\n", assemblyFolders)}");
}
return assemblyFolders.ToArray();
}
#if !UNITY_2021_3_OR_NEWER
private static Dictionary<string, string> GetPackagesLookup()
{
var packages = new Dictionary<string, string>();
// Fetch list of packages
#if UNITY_2021_1_OR_NEWER
var allPackages = UnityEditor.PackageManager.PackageInfo.GetAllRegisteredPackages();
#else
var allPackages = UnityEditor.PackageManager.PackageInfo.GetAll();
#endif
foreach (var p in allPackages)
{
packages.Add(p.name, p.resolvedPath);
}
return packages;
}
private const string PackagesPath = "Packages/";
private static readonly int PackagesPathLength = PackagesPath.Length;
private static bool TryResolvePath(string path, Dictionary<string, string> packagesLookup, out string resolvedPath)
{
if (string.IsNullOrEmpty(path))
{
resolvedPath = null;
return false;
}
else if (path.StartsWith("Packages/", StringComparison.InvariantCulture))
{
var secondSlashIndex = path.IndexOf('/', PackagesPathLength);
var packageName = secondSlashIndex > -1
? path.Substring(PackagesPathLength, secondSlashIndex - PackagesPathLength)
: path.Substring(PackagesPathLength);
if (packagesLookup.TryGetValue(packageName, out var resolvedPathTemp))
{
path = secondSlashIndex > -1
? Path.Combine(resolvedPathTemp, path.Substring(secondSlashIndex + 1))
: resolvedPathTemp;
}
else
{
if (IsDebugging)
{
UnityEngine.Debug.Log($"{DateTime.UtcNow} Burst - unknown package path '{path}'");
}
resolvedPath = null;
return false;
}
}
resolvedPath = Path.GetFullPath(path);
return true;
}
#endif
private static void OnCompilationFinished(object value)
{
if (_currentBuildKind!=CompilationTaskReason.IsForEditor)
{
if (IsDebugging)
{
UnityEngine.Debug.Log($"{DateTime.UtcNow} Burst - ignoring finished compilation '{value}' because it's '{_currentBuildKind}'");
}
_currentBuildKind = CompilationTaskReason.IsForEditor;
return;
}
if (IsDebugging)
{
UnityEngine.Debug.Log($"{DateTime.UtcNow} Burst - compilation finished for '{value}'");
}
BurstCompiler.NotifyCompilationFinished();
}
#if UNITY_2021_1_OR_NEWER
private static void OnAssemblyCompilationFinished(ScriptAssembly assembly, CompilerMessage[] messages)
#else
private static void OnAssemblyCompilationFinished(ScriptAssembly assembly, CompilerMessage[] messages, EditorScriptCompilationOptions options)
#endif
{
if (_currentBuildKind!=CompilationTaskReason.IsForEditor)
{
if (IsDebugging)
{
UnityEngine.Debug.Log($"{DateTime.UtcNow} Burst - ignoring '{assembly.Filename}' because it's '{_currentBuildKind}'");
}
return;
}
if (IsDebugging)
{
UnityEngine.Debug.Log($"{DateTime.UtcNow} Burst - Assembly compilation finished for '{assembly.Filename}'");
}
if (assembly.HasCompileErrors)
{
if (IsDebugging)
{
UnityEngine.Debug.Log($"{DateTime.UtcNow} Burst - ignoring '{assembly.Filename}' because it failed C# compilation");
}
return;
}
BurstCompiler.NotifyAssemblyCompilationFinished(Path.GetFileNameWithoutExtension(assembly.Filename), assembly.Defines);
}
private static void OnAssemblyCompilationNotRequired(string arg1)
{
if (_currentBuildKind!=CompilationTaskReason.IsForEditor)
{
if (IsDebugging)
{
UnityEngine.Debug.Log($"{DateTime.UtcNow} Burst - ignoring '{arg1}' because it's '{_currentBuildKind}'");
}
return;
}
if (IsDebugging)
{
UnityEngine.Debug.Log($"{DateTime.UtcNow} Burst - Assembly compilation not required for '{arg1}'");
}
BurstCompiler.NotifyAssemblyCompilationNotRequired(Path.GetFileNameWithoutExtension(arg1));
}
private static bool TryGetOptionsFromMember(MemberInfo member, out string flagsOut)
{
return BurstCompiler.Options.TryGetOptions(member, out flagsOut);
}
private static void OnDomainUnload(object sender, EventArgs e)
{
if (IsDebugging)
{
UnityEngine.Debug.Log($"Burst - OnDomainUnload");
}
BurstCompiler.Cancel();
// This check here is to execute shutdown after all OnDisable's. EditorApplication.quitting event is called before OnDisable's, so we need to shutdown in here.
if (_isQuitting)
{
BurstCompiler.Shutdown();
}
// Because of a check in Unity (specifically SCRIPTINGAPI_THREAD_AND_SERIALIZATION_CHECK),
// we are not allowed to call thread-unsafe methods (like Progress.Exists) after the
// kApplicationTerminating bit has been set. And because the domain is unloaded
// (thus triggering AppDomain.DomainUnload) *after* that bit is set, we can't call Progress.Exists
// during shutdown. So we check _isQuitting here. When quitting, it's fine for the progress item
// not to be removed since it's all being torn down anyway.
if (!_isQuitting && Progress.Exists(BurstProgressId))
{
Progress.Remove(BurstProgressId);
BurstProgressId = -1;
}
}
}
internal class BclConfiguration
{
public string FolderPath { get; set; }
public string ExecutablePath { get; set; }
public bool IsExecutableNative { get; set; }
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: aeb3ace3d48330a3b182da7ace6b5f65
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,644 @@
#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using Unity.Jobs.LowLevel.Unsafe;
using UnityEditor;
using UnityEditor.Compilation;
using Debug = UnityEngine.Debug;
[assembly: InternalsVisibleTo("Unity.Burst.Editor.Tests")]
namespace Unity.Burst.Editor
{
using static BurstCompilerOptions;
internal static class BurstReflection
{
// The TypeCache API was added in 2019.2. So there are two versions of FindExecuteMethods,
// one that uses TypeCache and one that doesn't.
public static FindExecuteMethodsResult FindExecuteMethods(List<System.Reflection.Assembly> assemblyList, BurstReflectionAssemblyOptions options)
{
var methodsToCompile = new List<BurstCompileTarget>();
var methodsToCompileSet = new HashSet<MethodInfo>();
var logMessages = new List<LogMessage>();
var interfaceToProducer = new Dictionary<Type, Type>();
var assemblySet = new HashSet<System.Reflection.Assembly>(assemblyList);
void AddTarget(BurstCompileTarget target)
{
if (target.Method.Name.EndsWith("$BurstManaged")) return;
// We will not try to record more than once a method in the methods to compile
// This can happen if a job interface is inheriting from another job interface which are using in the end the same
// job producer type
if (!target.IsStaticMethod && !methodsToCompileSet.Add(target.Method))
{
return;
}
if (options.HasFlag(BurstReflectionAssemblyOptions.ExcludeTestAssemblies) &&
target.JobType.Assembly.GetReferencedAssemblies().Any(x => IsNUnitDll(x.Name)))
{
return;
}
methodsToCompile.Add(target);
}
var staticMethodTypes = new HashSet<Type>();
// -------------------------------------------
// Find job structs using TypeCache.
// -------------------------------------------
var jobProducerImplementations = TypeCache.GetTypesWithAttribute<JobProducerTypeAttribute>();
foreach (var jobProducerImplementation in jobProducerImplementations)
{
var attrs = jobProducerImplementation.GetCustomAttributes(typeof(JobProducerTypeAttribute), false);
if (attrs.Length == 0)
{
continue;
}
staticMethodTypes.Add(jobProducerImplementation);
var attr = (JobProducerTypeAttribute)attrs[0];
interfaceToProducer.Add(jobProducerImplementation, attr.ProducerType);
}
foreach (var jobProducerImplementation in jobProducerImplementations)
{
if (!jobProducerImplementation.IsInterface)
{
continue;
}
var jobTypes = TypeCache.GetTypesDerivedFrom(jobProducerImplementation);
foreach (var jobType in jobTypes)
{
if (jobType.IsGenericType || !jobType.IsValueType)
{
continue;
}
ScanJobType(jobType, interfaceToProducer, logMessages, AddTarget);
}
}
// -------------------------------------------
// Find static methods using TypeCache.
// -------------------------------------------
void AddStaticMethods(TypeCache.MethodCollection methods)
{
foreach (var method in methods)
{
if (HasBurstCompileAttribute(method.DeclaringType))
{
staticMethodTypes.Add(method.DeclaringType);
// NOTE: Make sure that we don't use a value type generic definition (e.g `class Outer<T> { struct Inner { } }`)
// We are only working on plain type or generic type instance!
if (!method.DeclaringType.IsGenericTypeDefinition &&
method.IsStatic &&
!method.ContainsGenericParameters)
{
AddTarget(new BurstCompileTarget(method, method.DeclaringType, null, true));
}
}
}
}
// Add [BurstCompile] static methods.
AddStaticMethods(TypeCache.GetMethodsWithAttribute<BurstCompileAttribute>());
// Add [TestCompiler] static methods.
if (!options.HasFlag(BurstReflectionAssemblyOptions.ExcludeTestAssemblies))
{
var testCompilerAttributeType = Type.GetType("Burst.Compiler.IL.Tests.TestCompilerAttribute, Unity.Burst.Tests.UnitTests, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
if (testCompilerAttributeType != null)
{
AddStaticMethods(TypeCache.GetMethodsWithAttribute(testCompilerAttributeType));
}
}
// -------------------------------------------
// Find job types and static methods based on
// generic instances types. These will not be
// found by the TypeCache scanning above.
// -------------------------------------------
FindExecuteMethodsForGenericInstances(
assemblySet,
staticMethodTypes,
interfaceToProducer,
AddTarget,
logMessages);
return new FindExecuteMethodsResult(methodsToCompile, logMessages);
}
private static void ScanJobType(
Type jobType,
Dictionary<Type, Type> interfaceToProducer,
List<LogMessage> logMessages,
Action<BurstCompileTarget> addTarget)
{
foreach (var interfaceType in jobType.GetInterfaces())
{
var genericLessInterface = interfaceType;
if (interfaceType.IsGenericType)
{
genericLessInterface = interfaceType.GetGenericTypeDefinition();
}
if (interfaceToProducer.TryGetValue(genericLessInterface, out var foundProducer))
{
var genericParams = new List<Type> { jobType };
if (interfaceType.IsGenericType)
{
genericParams.AddRange(interfaceType.GenericTypeArguments);
}
try
{
var executeType = foundProducer.MakeGenericType(genericParams.ToArray());
var executeMethod = executeType.GetMethod("Execute", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
if (executeMethod == null)
{
throw new InvalidOperationException($"Burst reflection error. The type `{executeType}` does not contain an `Execute` method");
}
addTarget(new BurstCompileTarget(executeMethod, jobType, interfaceType, false));
}
catch (Exception ex)
{
logMessages.Add(new LogMessage(ex));
}
}
}
}
private static void FindExecuteMethodsForGenericInstances(
HashSet<System.Reflection.Assembly> assemblyList,
HashSet<Type> staticMethodTypes,
Dictionary<Type, Type> interfaceToProducer,
Action<BurstCompileTarget> addTarget,
List<LogMessage> logMessages)
{
var valueTypes = new List<TypeToVisit>();
//Debug.Log("Filtered Assembly List: " + string.Join(", ", assemblyList.Select(assembly => assembly.GetName().Name)));
// Find all ways to execute job types (via producer attributes)
var typesVisited = new HashSet<string>();
var typesToVisit = new HashSet<string>();
var allTypesAssembliesCollected = new HashSet<Type>();
foreach (var assembly in assemblyList)
{
var types = new List<Type>();
try
{
// Collect all generic type instances (excluding indirect instances)
CollectGenericTypeInstances(
assembly,
x => assemblyList.Contains(x.Assembly),
types,
allTypesAssembliesCollected);
}
catch (Exception ex)
{
logMessages.Add(new LogMessage(LogType.Warning, "Unexpected exception while collecting types in assembly `" + assembly.FullName + "` Exception: " + ex));
}
for (var i = 0; i < types.Count; i++)
{
var t = types[i];
if (typesToVisit.Add(t.AssemblyQualifiedName))
{
// Because the list of types returned by CollectGenericTypeInstances does not detect nested generic classes that are not
// used explicitly, we need to create them if a declaring type is actually used
// so for example if we have:
// class MyClass<T> { class MyNestedClass { } }
// class MyDerived : MyClass<int> { }
// The CollectGenericTypeInstances will return typically the type MyClass<int>, but will not list MyClass<int>.MyNestedClass
// So the following code is correcting this in order to fully query the full graph of generic instance types, including indirect types
var nestedTypes = t.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic);
foreach (var nestedType in nestedTypes)
{
if (t.IsGenericType && !t.IsGenericTypeDefinition)
{
var parentGenericTypeArguments = t.GetGenericArguments();
// Only create nested types that are closed generic types (full generic instance types)
// It happens if for example the parent class is `class MClass<T> { class MyNestedGeneric<T1> {} }`
// In that case, MyNestedGeneric<T1> is opened in the context of MClass<int>, so we don't process them
if (nestedType.GetGenericArguments().Length == parentGenericTypeArguments.Length)
{
try
{
var instanceNestedType = nestedType.MakeGenericType(parentGenericTypeArguments);
types.Add(instanceNestedType);
}
catch (Exception ex)
{
var error = $"Unexpected Burst Inspector error. Invalid generic type instance. Trying to instantiate the generic type {nestedType.FullName} with the generic arguments <{string.Join(", ", parentGenericTypeArguments.Select(x => x.FullName))}> is not supported: {ex}";
logMessages.Add(new LogMessage(LogType.Warning, error));
}
}
}
else
{
types.Add(nestedType);
}
}
}
}
foreach (var t in types)
{
// If the type has been already visited, don't try to visit it
if (!typesVisited.Add(t.AssemblyQualifiedName) || (t.IsGenericTypeDefinition && !t.IsInterface))
{
continue;
}
try
{
// collect methods with types having a [BurstCompile] attribute
var staticMethodDeclaringType = t;
if (t.IsGenericType)
{
staticMethodDeclaringType = t.GetGenericTypeDefinition();
}
bool visitStaticMethods = staticMethodTypes.Contains(staticMethodDeclaringType);
bool isValueType = false;
if (t.IsValueType)
{
// NOTE: Make sure that we don't use a value type generic definition (e.g `class Outer<T> { struct Inner { } }`)
// We are only working on plain type or generic type instance!
if (!t.IsGenericTypeDefinition)
isValueType = true;
}
if (isValueType || visitStaticMethods)
{
valueTypes.Add(new TypeToVisit(t, visitStaticMethods));
}
}
catch (Exception ex)
{
logMessages.Add(new LogMessage(LogType.Warning,
"Unexpected exception while inspecting type `" + t +
"` IsConstructedGenericType: " + t.IsConstructedGenericType +
" IsGenericTypeDef: " + t.IsGenericTypeDefinition +
" IsGenericParam: " + t.IsGenericParameter +
" Exception: " + ex));
}
}
}
// Revisit all types to find things that are compilable using the above producers.
foreach (var typePair in valueTypes)
{
var type = typePair.Type;
// collect static [BurstCompile] methods
if (typePair.CollectStaticMethods)
{
try
{
var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
foreach (var method in methods)
{
if (HasBurstCompileAttribute(method))
{
addTarget(new BurstCompileTarget(method, type, null, true));
}
}
}
catch (Exception ex)
{
logMessages.Add(new LogMessage(ex));
}
}
// If the type is not a value type, we don't need to proceed with struct Jobs
if (!type.IsValueType)
{
continue;
}
ScanJobType(type, interfaceToProducer, logMessages, addTarget);
}
}
public sealed class FindExecuteMethodsResult
{
public readonly List<BurstCompileTarget> CompileTargets;
public readonly List<LogMessage> LogMessages;
public FindExecuteMethodsResult(List<BurstCompileTarget> compileTargets, List<LogMessage> logMessages)
{
CompileTargets = compileTargets;
LogMessages = logMessages;
}
}
public sealed class LogMessage
{
public readonly LogType LogType;
public readonly string Message;
public readonly Exception Exception;
public LogMessage(LogType logType, string message)
{
LogType = logType;
Message = message;
}
public LogMessage(Exception exception)
{
LogType = LogType.Exception;
Exception = exception;
}
}
public enum LogType
{
Warning,
Exception,
}
/// <summary>
/// This method exists solely to ensure that the static constructor has been called.
/// </summary>
public static void EnsureInitialized() { }
public static readonly List<System.Reflection.Assembly> EditorAssembliesThatCanPossiblyContainJobs;
public static readonly List<System.Reflection.Assembly> EditorAssembliesThatCanPossiblyContainJobsExcludingTestAssemblies;
/// <summary>
/// Collects (and caches) all editor assemblies - transitively.
/// </summary>
static BurstReflection()
{
EditorAssembliesThatCanPossiblyContainJobs = new List<System.Reflection.Assembly>();
EditorAssembliesThatCanPossiblyContainJobsExcludingTestAssemblies = new List<System.Reflection.Assembly>();
// TODO: Not sure there is a better way to match assemblies returned by CompilationPipeline.GetAssemblies
// with runtime assemblies contained in the AppDomain.CurrentDomain.GetAssemblies()
// Filter the assemblies
var assemblyList = CompilationPipeline.GetAssemblies(AssembliesType.Editor);
var assemblyNames = new HashSet<string>();
foreach (var assembly in assemblyList)
{
CollectAssemblyNames(assembly, assemblyNames);
}
var allAssemblies = new HashSet<System.Reflection.Assembly>();
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
if (!assemblyNames.Contains(assembly.GetName().Name))
{
continue;
}
CollectAssembly(assembly, allAssemblies);
}
}
// For an assembly to contain something "interesting" when we're scanning for things to compile,
// it needs to either:
// (a) be one of these assemblies, or
// (b) reference one of these assemblies
private static readonly string[] ScanMarkerAssemblies = new[]
{
// Contains [BurstCompile] attribute
"Unity.Burst",
// Contains [JobProducerType] attribute
"UnityEngine.CoreModule"
};
private static void CollectAssembly(System.Reflection.Assembly assembly, HashSet<System.Reflection.Assembly> collect)
{
if (!collect.Add(assembly))
{
return;
}
var referencedAssemblies = assembly.GetReferencedAssemblies();
var shouldCollectReferences = false;
var name = assembly.GetName().Name;
if (ScanMarkerAssemblies.Contains(name) || referencedAssemblies.Any(x => ScanMarkerAssemblies.Contains(x.Name)))
{
EditorAssembliesThatCanPossiblyContainJobs.Add(assembly);
shouldCollectReferences = true;
if (!assembly.GetReferencedAssemblies().Any(x => IsNUnitDll(x.Name)))
{
EditorAssembliesThatCanPossiblyContainJobsExcludingTestAssemblies.Add(assembly);
}
}
if (!shouldCollectReferences)
{
return;
}
foreach (var assemblyName in referencedAssemblies)
{
try
{
CollectAssembly(System.Reflection.Assembly.Load(assemblyName), collect);
}
catch (Exception)
{
if (BurstLoader.IsDebugging)
{
Debug.LogWarning("Could not load assembly " + assemblyName);
}
}
}
}
private static bool IsNUnitDll(string value)
{
return CultureInfo.InvariantCulture.CompareInfo.IndexOf(value, "nunit.framework") >= 0;
}
private static void CollectAssemblyNames(UnityEditor.Compilation.Assembly assembly, HashSet<string> collect)
{
if (assembly == null || assembly.name == null) return;
if (!collect.Add(assembly.name))
{
return;
}
foreach (var assemblyRef in assembly.assemblyReferences)
{
CollectAssemblyNames(assemblyRef, collect);
}
}
/// <summary>
/// Gets the list of concrete generic type instances used in an assembly.
/// See remarks
/// </summary>
/// <param name="assembly">The assembly</param>
/// <param name="types"></param>
/// <returns>The list of generic type instances</returns>
/// <remarks>
/// Note that this method fetchs only direct type instances but
/// cannot fetch transitive generic type instances.
/// </remarks>
private static void CollectGenericTypeInstances(
System.Reflection.Assembly assembly,
Func<Type, bool> typeFilter,
List<Type> types,
HashSet<Type> visited)
{
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// WARNING: THIS CODE HAS TO BE MAINTAINED IN SYNC WITH BclApp.cs
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// From: https://gist.github.com/xoofx/710aaf86e0e8c81649d1261b1ef9590e
if (assembly == null) throw new ArgumentNullException(nameof(assembly));
const int mdMaxCount = 1 << 24;
foreach (var module in assembly.Modules)
{
for (int i = 1; i < mdMaxCount; i++)
{
try
{
// Token base id for TypeSpec
const int mdTypeSpec = 0x1B000000;
var type = module.ResolveType(mdTypeSpec | i);
CollectGenericTypeInstances(type, types, visited, typeFilter);
}
catch (ArgumentOutOfRangeException)
{
break;
}
catch (ArgumentException)
{
// Can happen on ResolveType on certain generic types, so we continue
}
}
for (int i = 1; i < mdMaxCount; i++)
{
try
{
// Token base id for MethodSpec
const int mdMethodSpec = 0x2B000000;
var method = module.ResolveMethod(mdMethodSpec | i);
var genericArgs = method.GetGenericArguments();
foreach (var genArgType in genericArgs)
{
CollectGenericTypeInstances(genArgType, types, visited, typeFilter);
}
}
catch (ArgumentOutOfRangeException)
{
break;
}
catch (ArgumentException)
{
// Can happen on ResolveType on certain generic types, so we continue
}
}
for (int i = 1; i < mdMaxCount; i++)
{
try
{
// Token base id for Field
const int mdField = 0x04000000;
var field = module.ResolveField(mdField | i);
CollectGenericTypeInstances(field.FieldType, types, visited, typeFilter);
}
catch (ArgumentOutOfRangeException)
{
break;
}
catch (ArgumentException)
{
// Can happen on ResolveType on certain generic types, so we continue
}
}
}
// Scan for types used in constructor arguments to assembly-level attributes,
// such as [RegisterGenericJobType(typeof(...))].
foreach (var customAttribute in assembly.CustomAttributes)
{
foreach (var argument in customAttribute.ConstructorArguments)
{
if (argument.ArgumentType == typeof(Type))
{
CollectGenericTypeInstances((Type)argument.Value, types, visited, typeFilter);
}
}
}
}
private static void CollectGenericTypeInstances(
Type type,
List<Type> types,
HashSet<Type> visited,
Func<Type, bool> typeFilter)
{
if (type.IsPrimitive) return;
if (!visited.Add(type)) return;
// Add only concrete types
if (type.IsConstructedGenericType && !type.ContainsGenericParameters && typeFilter(type))
{
types.Add(type);
}
// Collect recursively generic type arguments
var genericTypeArguments = type.GenericTypeArguments;
foreach (var genericTypeArgument in genericTypeArguments)
{
if (!genericTypeArgument.IsPrimitive)
{
CollectGenericTypeInstances(genericTypeArgument, types, visited, typeFilter);
}
}
}
[DebuggerDisplay("{Type} (static methods: {CollectStaticMethods})")]
private struct TypeToVisit
{
public TypeToVisit(Type type, bool collectStaticMethods)
{
Type = type;
CollectStaticMethods = collectStaticMethods;
}
public readonly Type Type;
public readonly bool CollectStaticMethods;
}
}
[Flags]
internal enum BurstReflectionAssemblyOptions
{
None = 0,
ExcludeTestAssemblies = 1,
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 661ba2a1bdac339cb55c6a43b9eaa0ee
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,3 @@
{
"reference": "Unity.Burst"
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 268a64be2367b3248a24f317d458861a
AssemblyDefinitionReferenceImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,84 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Unity.Collections.LowLevel.Unsafe;
namespace Unity.Burst
{
/// <summary>
/// Base interface for a function pointer.
/// </summary>
public interface IFunctionPointer
{
/// <summary>
/// Converts a pointer to a function pointer.
/// </summary>
/// <param name="ptr">The native pointer.</param>
/// <returns>An instance of this interface.</returns>
[Obsolete("This method will be removed in a future version of Burst")]
IFunctionPointer FromIntPtr(IntPtr ptr);
}
/// <summary>
/// A function pointer that can be used from a Burst Job or from regular C#.
/// It needs to be compiled through <see cref="BurstCompiler.CompileFunctionPointer{T}"/>
/// </summary>
/// <typeparam name="T">Type of the delegate of this function pointer</typeparam>
public readonly struct FunctionPointer<T> : IFunctionPointer
{
// DOTSPLAYER's shim package relies on Burst for it's jobs code
// so Burst does not see the DOTSPLAYER definition of this attribute
[NativeDisableUnsafePtrRestriction]
private readonly IntPtr _ptr;
/// <summary>
/// Creates a new instance of this function pointer with the following native pointer.
/// </summary>
/// <param name="ptr">Native Pointer</param>
public FunctionPointer(IntPtr ptr)
{
_ptr = ptr;
}
/// <summary>
/// Gets the underlying pointer.
/// </summary>
public IntPtr Value => _ptr;
[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
private void CheckIsCreated()
{
if (!IsCreated)
{
throw new NullReferenceException("Object reference not set to an instance of an object");
}
}
/// <summary>
/// Gets the delegate associated to this function pointer in order to call the function pointer.
/// This delegate can be called from a Burst Job or from regular C#.
/// If calling from regular C#, it is recommended to cache the returned delegate of this property
/// instead of using this property every time you need to call the delegate.
/// </summary>
public T Invoke
{
get
{
CheckIsCreated();
return Marshal.GetDelegateForFunctionPointer<T>(_ptr);
}
}
/// <summary>
/// Whether the function pointer is valid.
/// </summary>
public bool IsCreated => _ptr != IntPtr.Zero;
/// <summary>
/// Converts a pointer to a function pointer.
/// </summary>
/// <param name="ptr">The native pointer.</param>
/// <returns>An instance of this interface.</returns>
IFunctionPointer IFunctionPointer.FromIntPtr(IntPtr ptr) => new FunctionPointer<T>(ptr);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d0f0ce9b0e7739228810ce3bc2330437
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6fbd9c5e397237e28650cb957742c782
folderAsset: yes

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2893f6d998ac3104919ec7e11aa597cd
folderAsset: yes

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ae0e31ea75d231429bb22041f90ea890
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a097ced0beed3e04abd3fa933657e0c3
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,262 @@
using System;
using System.Diagnostics;
namespace Unity.Burst.Intrinsics
{
public unsafe static partial class Arm
{
public unsafe partial class Neon
{
/// <summary>
/// Evaluates to true at compile time if Armv8.1 Crypto intrinsics (AES, SHA1, SHA2, CRC32) are supported.
/// </summary>
public static bool IsNeonCryptoSupported { get { return false; } }
/// <summary>SHA1 hash update (choose).
/// <br/>Equivalent instruction: <c>SHA1C Qd,Sn,Vm.4S</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">UInt32 a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vsha1cq_u32(v128 a0, UInt32 a1, v128 a2)
{
throw new NotImplementedException();
}
/// <summary>SHA1 hash update (parity).
/// <br/>Equivalent instruction: <c>SHA1P Qd,Sn,Vm.4S</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">UInt32 a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vsha1pq_u32(v128 a0, UInt32 a1, v128 a2)
{
throw new NotImplementedException();
}
/// <summary>SHA1 hash update (majority).
/// <br/>Equivalent instruction: <c>SHA1M Qd,Sn,Vm.4S</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">UInt32 a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vsha1mq_u32(v128 a0, UInt32 a1, v128 a2)
{
throw new NotImplementedException();
}
/// <summary>SHA1 fixed rotate.
/// <br/>Equivalent instruction: <c>SHA1H Sd,Sn</c></summary>
/// <param name="a0">UInt32 a0</param>
/// <returns>UInt32</returns>
[DebuggerStepThrough]
public static UInt32 vsha1h_u32(UInt32 a0)
{
throw new NotImplementedException();
}
/// <summary>SHA1 schedule update 0.
/// <br/>Equivalent instruction: <c>SHA1SU0 Vd.4S,Vn.4S,Vm.4S</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vsha1su0q_u32(v128 a0, v128 a1, v128 a2)
{
throw new NotImplementedException();
}
/// <summary>SHA1 schedule update 1.
/// <br/>Equivalent instruction: <c>SHA1SU1 Vd.4S,Vn.4S</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vsha1su1q_u32(v128 a0, v128 a1)
{
throw new NotImplementedException();
}
/// <summary>SHA256 hash update (part 1).
/// <br/>Equivalent instruction: <c>SHA256H Qd,Qn,Vm.4S</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vsha256hq_u32(v128 a0, v128 a1, v128 a2)
{
throw new NotImplementedException();
}
/// <summary>SHA256 hash update (part 2).
/// <br/>Equivalent instruction: <c>SHA256H2 Qd,Qn,Vm.4S</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vsha256h2q_u32(v128 a0, v128 a1, v128 a2)
{
throw new NotImplementedException();
}
/// <summary>SHA256 schedule update 0.
/// <br/>Equivalent instruction: <c>SHA256SU0 Vd.4S,Vn.4S</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vsha256su0q_u32(v128 a0, v128 a1)
{
throw new NotImplementedException();
}
/// <summary>SHA256 schedule update 1.
/// <br/>Equivalent instruction: <c>SHA256SU1 Vd.4S,Vn.4S,Vm.4S</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vsha256su1q_u32(v128 a0, v128 a1, v128 a2)
{
throw new NotImplementedException();
}
/// <summary>CRC32 checksum performs a cyclic redundancy check (CRC) calculation on a value held in a general-purpose register. It takes an input CRC value in the first source operand, performs a CRC on the input value in the second source operand, and returns the output CRC value. The second source operand can be 8, 16, 32, or 64 bits. To align with common usage, the bit order of the values is reversed as part of the operation, and the polynomial 0x04C11DB7 is used for the CRC calculation.
/// <br/>Equivalent instruction: <c>CRC32B Wd,Wn,Wm</c></summary>
/// <param name="a0">UInt32 a0</param>
/// <param name="a1">Byte a1</param>
/// <returns>UInt32</returns>
[DebuggerStepThrough]
public static UInt32 __crc32b(UInt32 a0, Byte a1)
{
throw new NotImplementedException();
}
/// <summary>CRC32 checksum performs a cyclic redundancy check (CRC) calculation on a value held in a general-purpose register. It takes an input CRC value in the first source operand, performs a CRC on the input value in the second source operand, and returns the output CRC value. The second source operand can be 8, 16, 32, or 64 bits. To align with common usage, the bit order of the values is reversed as part of the operation, and the polynomial 0x04C11DB7 is used for the CRC calculation.
/// <br/>Equivalent instruction: <c>CRC32H Wd,Wn,Wm</c></summary>
/// <param name="a0">UInt32 a0</param>
/// <param name="a1">UInt16 a1</param>
/// <returns>UInt32</returns>
[DebuggerStepThrough]
public static UInt32 __crc32h(UInt32 a0, UInt16 a1)
{
throw new NotImplementedException();
}
/// <summary>CRC32 checksum performs a cyclic redundancy check (CRC) calculation on a value held in a general-purpose register. It takes an input CRC value in the first source operand, performs a CRC on the input value in the second source operand, and returns the output CRC value. The second source operand can be 8, 16, 32, or 64 bits. To align with common usage, the bit order of the values is reversed as part of the operation, and the polynomial 0x04C11DB7 is used for the CRC calculation.
/// <br/>Equivalent instruction: <c>CRC32W Wd,Wn,Wm</c></summary>
/// <param name="a0">UInt32 a0</param>
/// <param name="a1">UInt32 a1</param>
/// <returns>UInt32</returns>
[DebuggerStepThrough]
public static UInt32 __crc32w(UInt32 a0, UInt32 a1)
{
throw new NotImplementedException();
}
/// <summary>CRC32 checksum performs a cyclic redundancy check (CRC) calculation on a value held in a general-purpose register. It takes an input CRC value in the first source operand, performs a CRC on the input value in the second source operand, and returns the output CRC value. The second source operand can be 8, 16, 32, or 64 bits. To align with common usage, the bit order of the values is reversed as part of the operation, and the polynomial 0x04C11DB7 is used for the CRC calculation.
/// <br/>Equivalent instruction: <c>CRC32X Wd,Wn,Xm</c></summary>
/// <param name="a0">UInt32 a0</param>
/// <param name="a1">UInt64 a1</param>
/// <returns>UInt32</returns>
[DebuggerStepThrough]
public static UInt32 __crc32d(UInt32 a0, UInt64 a1)
{
throw new NotImplementedException();
}
/// <summary>CRC32 checksum performs a cyclic redundancy check (CRC) calculation on a value held in a general-purpose register. It takes an input CRC value in the first source operand, performs a CRC on the input value in the second source operand, and returns the output CRC value. The second source operand can be 8, 16, 32, or 64 bits. To align with common usage, the bit order of the values is reversed as part of the operation, and the polynomial 0x04C11DB7 is used for the CRC calculation.
/// <br/>Equivalent instruction: <c>CRC32CB Wd,Wn,Wm</c></summary>
/// <param name="a0">UInt32 a0</param>
/// <param name="a1">Byte a1</param>
/// <returns>UInt32</returns>
[DebuggerStepThrough]
public static UInt32 __crc32cb(UInt32 a0, Byte a1)
{
throw new NotImplementedException();
}
/// <summary>CRC32 checksum performs a cyclic redundancy check (CRC) calculation on a value held in a general-purpose register. It takes an input CRC value in the first source operand, performs a CRC on the input value in the second source operand, and returns the output CRC value. The second source operand can be 8, 16, 32, or 64 bits. To align with common usage, the bit order of the values is reversed as part of the operation, and the polynomial 0x04C11DB7 is used for the CRC calculation.
/// <br/>Equivalent instruction: <c>CRC32CH Wd,Wn,Wm</c></summary>
/// <param name="a0">UInt32 a0</param>
/// <param name="a1">UInt16 a1</param>
/// <returns>UInt32</returns>
[DebuggerStepThrough]
public static UInt32 __crc32ch(UInt32 a0, UInt16 a1)
{
throw new NotImplementedException();
}
/// <summary>CRC32 checksum performs a cyclic redundancy check (CRC) calculation on a value held in a general-purpose register. It takes an input CRC value in the first source operand, performs a CRC on the input value in the second source operand, and returns the output CRC value. The second source operand can be 8, 16, 32, or 64 bits. To align with common usage, the bit order of the values is reversed as part of the operation, and the polynomial 0x04C11DB7 is used for the CRC calculation.
/// <br/>Equivalent instruction: <c>CRC32CW Wd,Wn,Wm</c></summary>
/// <param name="a0">UInt32 a0</param>
/// <param name="a1">UInt32 a1</param>
/// <returns>UInt32</returns>
[DebuggerStepThrough]
public static UInt32 __crc32cw(UInt32 a0, UInt32 a1)
{
throw new NotImplementedException();
}
/// <summary>CRC32 checksum performs a cyclic redundancy check (CRC) calculation on a value held in a general-purpose register. It takes an input CRC value in the first source operand, performs a CRC on the input value in the second source operand, and returns the output CRC value. The second source operand can be 8, 16, 32, or 64 bits. To align with common usage, the bit order of the values is reversed as part of the operation, and the polynomial 0x04C11DB7 is used for the CRC calculation.
/// <br/>Equivalent instruction: <c>CRC32CX Wd,Wn,Xm</c></summary>
/// <param name="a0">UInt32 a0</param>
/// <param name="a1">UInt64 a1</param>
/// <returns>UInt32</returns>
[DebuggerStepThrough]
public static UInt32 __crc32cd(UInt32 a0, UInt64 a1)
{
throw new NotImplementedException();
}
/// <summary>AES single round encryption.
/// <br/>Equivalent instruction: <c>AESE Vd.16B,Vn.16B</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vaeseq_u8(v128 a0, v128 a1)
{
throw new NotImplementedException();
}
/// <summary>AES single round decryption.
/// <br/>Equivalent instruction: <c>AESD Vd.16B,Vn.16B</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vaesdq_u8(v128 a0, v128 a1)
{
throw new NotImplementedException();
}
/// <summary>AES mix columns.
/// <br/>Equivalent instruction: <c>AESMC Vd.16B,Vn.16B</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vaesmcq_u8(v128 a0)
{
throw new NotImplementedException();
}
/// <summary>AES inverse mix columns.
/// <br/>Equivalent instruction: <c>AESIMC Vd.16B,Vn.16B</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vaesimcq_u8(v128 a0)
{
throw new NotImplementedException();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: db8f2de394d138e1967d236540227a26
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,168 @@
using System;
using System.Diagnostics;
namespace Unity.Burst.Intrinsics
{
public unsafe static partial class Arm
{
public unsafe partial class Neon
{
/// <summary>
/// Evaluates to true at compile time if Armv8.2 Dot Product intrinsics are supported.
/// </summary>
public static bool IsNeonDotProdSupported { get { return false; } }
/// <summary>Dot Product unsigned arithmetic (vector, by element). This instruction performs the dot product of the four 8-bit elements in each 32-bit element of the first source register with the four 8-bit elements of an indexed 32-bit element in the second source register, accumulating the result into the corresponding 32-bit element of the destination register.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is mandatory for all implementations to support it.ID_AA64ISAR0_EL1.DP indicates whether this instruction is supported.
/// <br/>Equivalent instruction: <c>UDOT Vd.2S,Vn.8B,Vm.8B</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vdot_u32(v64 a0, v64 a1, v64 a2)
{
throw new NotImplementedException();
}
/// <summary>Dot Product signed arithmetic (vector, by element). This instruction performs the dot product of the four 8-bit elements in each 32-bit element of the first source register with the four 8-bit elements of an indexed 32-bit element in the second source register, accumulating the result into the corresponding 32-bit element of the destination register.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is mandatory for all implementations to support it.ID_AA64ISAR0_EL1.DP indicates whether this instruction is supported.
/// <br/>Equivalent instruction: <c>SDOT Vd.2S,Vn.8B,Vm.8B</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vdot_s32(v64 a0, v64 a1, v64 a2)
{
throw new NotImplementedException();
}
/// <summary>Dot Product unsigned arithmetic (vector, by element). This instruction performs the dot product of the four 8-bit elements in each 32-bit element of the first source register with the four 8-bit elements of an indexed 32-bit element in the second source register, accumulating the result into the corresponding 32-bit element of the destination register.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is mandatory for all implementations to support it.ID_AA64ISAR0_EL1.DP indicates whether this instruction is supported.
/// <br/>Equivalent instruction: <c>UDOT Vd.4S,Vn.16B,Vm.16B</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vdotq_u32(v128 a0, v128 a1, v128 a2)
{
throw new NotImplementedException();
}
/// <summary>Dot Product signed arithmetic (vector, by element). This instruction performs the dot product of the four 8-bit elements in each 32-bit element of the first source register with the four 8-bit elements of an indexed 32-bit element in the second source register, accumulating the result into the corresponding 32-bit element of the destination register.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is mandatory for all implementations to support it.ID_AA64ISAR0_EL1.DP indicates whether this instruction is supported.
/// <br/>Equivalent instruction: <c>SDOT Vd.4S,Vn.16B,Vm.16B</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vdotq_s32(v128 a0, v128 a1, v128 a2)
{
throw new NotImplementedException();
}
/// <summary>Dot Product unsigned arithmetic (vector, by element). This instruction performs the dot product of the four 8-bit elements in each 32-bit element of the first source register with the four 8-bit elements of an indexed 32-bit element in the second source register, accumulating the result into the corresponding 32-bit element of the destination register.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is mandatory for all implementations to support it.ID_AA64ISAR0_EL1.DP indicates whether this instruction is supported.
/// <br/>Equivalent instruction: <c>UDOT Vd.2S,Vn.8B,Vm.4B[lane]</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..1]</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vdot_lane_u32(v64 a0, v64 a1, v64 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Dot Product signed arithmetic (vector, by element). This instruction performs the dot product of the four 8-bit elements in each 32-bit element of the first source register with the four 8-bit elements of an indexed 32-bit element in the second source register, accumulating the result into the corresponding 32-bit element of the destination register.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is mandatory for all implementations to support it.ID_AA64ISAR0_EL1.DP indicates whether this instruction is supported.
/// <br/>Equivalent instruction: <c>SDOT Vd.2S,Vn.8B,Vm.4B[lane]</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..1]</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vdot_lane_s32(v64 a0, v64 a1, v64 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Dot Product unsigned arithmetic (vector, by element). This instruction performs the dot product of the four 8-bit elements in each 32-bit element of the first source register with the four 8-bit elements of an indexed 32-bit element in the second source register, accumulating the result into the corresponding 32-bit element of the destination register.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is mandatory for all implementations to support it.ID_AA64ISAR0_EL1.DP indicates whether this instruction is supported.
/// <br/>Equivalent instruction: <c>UDOT Vd.4S,Vn.16B,Vm.4B[lane]</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..3]</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vdotq_laneq_u32(v128 a0, v128 a1, v128 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Dot Product signed arithmetic (vector, by element). This instruction performs the dot product of the four 8-bit elements in each 32-bit element of the first source register with the four 8-bit elements of an indexed 32-bit element in the second source register, accumulating the result into the corresponding 32-bit element of the destination register.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is mandatory for all implementations to support it.ID_AA64ISAR0_EL1.DP indicates whether this instruction is supported.
/// <br/>Equivalent instruction: <c>SDOT Vd.4S,Vn.16B,Vm.4B[lane]</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..3]</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vdotq_laneq_s32(v128 a0, v128 a1, v128 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Dot Product unsigned arithmetic (vector, by element). This instruction performs the dot product of the four 8-bit elements in each 32-bit element of the first source register with the four 8-bit elements of an indexed 32-bit element in the second source register, accumulating the result into the corresponding 32-bit element of the destination register.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is mandatory for all implementations to support it.ID_AA64ISAR0_EL1.DP indicates whether this instruction is supported.
/// <br/>Equivalent instruction: <c>UDOT Vd.2S,Vn.8B,Vm.4B[lane]</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..3]</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vdot_laneq_u32(v64 a0, v64 a1, v128 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Dot Product signed arithmetic (vector, by element). This instruction performs the dot product of the four 8-bit elements in each 32-bit element of the first source register with the four 8-bit elements of an indexed 32-bit element in the second source register, accumulating the result into the corresponding 32-bit element of the destination register.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is mandatory for all implementations to support it.ID_AA64ISAR0_EL1.DP indicates whether this instruction is supported.
/// <br/>Equivalent instruction: <c>SDOT Vd.2S,Vn.8B,Vm.4B[lane]</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..3]</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vdot_laneq_s32(v64 a0, v64 a1, v128 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Dot Product unsigned arithmetic (vector, by element). This instruction performs the dot product of the four 8-bit elements in each 32-bit element of the first source register with the four 8-bit elements of an indexed 32-bit element in the second source register, accumulating the result into the corresponding 32-bit element of the destination register.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is mandatory for all implementations to support it.ID_AA64ISAR0_EL1.DP indicates whether this instruction is supported.
/// <br/>Equivalent instruction: <c>UDOT Vd.4S,Vn.16B,Vm.4B[lane]</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..1]</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vdotq_lane_u32(v128 a0, v128 a1, v64 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Dot Product signed arithmetic (vector, by element). This instruction performs the dot product of the four 8-bit elements in each 32-bit element of the first source register with the four 8-bit elements of an indexed 32-bit element in the second source register, accumulating the result into the corresponding 32-bit element of the destination register.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is mandatory for all implementations to support it.ID_AA64ISAR0_EL1.DP indicates whether this instruction is supported.
/// <br/>Equivalent instruction: <c>SDOT Vd.4S,Vn.16B,Vm.4B[lane]</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..1]</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vdotq_lane_s32(v128 a0, v128 a1, v64 a2, Int32 a3)
{
throw new NotImplementedException();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ae2473ecba7e346e806e9120b6533cf4
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3280a6148aa83ec3be2f6892fa4d8e2d
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,446 @@
using System;
using System.Diagnostics;
namespace Unity.Burst.Intrinsics
{
public unsafe static partial class Arm
{
public unsafe partial class Neon
{
/// <summary>
/// Evaluates to true at compile time if Armv8.1 Rounding Double Multiply Add/Subtract intrinsics are supported.
/// </summary>
public static bool IsNeonRDMASupported { get { return false; } }
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Vd.4H,Vn.4H,Vm.4H</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vqrdmlah_s16(v64 a0, v64 a1, v64 a2)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Vd.2S,Vn.2S,Vm.2S</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vqrdmlah_s32(v64 a0, v64 a1, v64 a2)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Vd.8H,Vn.8H,Vm.8H</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vqrdmlahq_s16(v128 a0, v128 a1, v128 a2)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Vd.4S,Vn.4S,Vm.4S</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vqrdmlahq_s32(v128 a0, v128 a1, v128 a2)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Vd.4H,Vn.4H,Vm.4H</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vqrdmlsh_s16(v64 a0, v64 a1, v64 a2)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Vd.2S,Vn.2S,Vm.2S</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vqrdmlsh_s32(v64 a0, v64 a1, v64 a2)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Vd.8H,Vn.8H,Vm.8H</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vqrdmlshq_s16(v128 a0, v128 a1, v128 a2)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Vd.4S,Vn.4S,Vm.4S</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vqrdmlshq_s32(v128 a0, v128 a1, v128 a2)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Vd.4H,Vn.4H,Vm.H[lane]</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..3]</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vqrdmlah_lane_s16(v64 a0, v64 a1, v64 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Vd.8H,Vn.8H,Vm.H[lane]</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..3]</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vqrdmlahq_lane_s16(v128 a0, v128 a1, v64 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Vd.4H,Vn.4H,Vm.H[lane]</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..7]</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vqrdmlah_laneq_s16(v64 a0, v64 a1, v128 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Vd.8H,Vn.8H,Vm.H[lane]</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..7]</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vqrdmlahq_laneq_s16(v128 a0, v128 a1, v128 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Vd.2S,Vn.2S,Vm.S[lane]</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..1]</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vqrdmlah_lane_s32(v64 a0, v64 a1, v64 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Vd.4S,Vn.4S,Vm.S[lane]</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..1]</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vqrdmlahq_lane_s32(v128 a0, v128 a1, v64 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Vd.2S,Vn.2S,Vm.S[lane]</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..3]</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vqrdmlah_laneq_s32(v64 a0, v64 a1, v128 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Vd.4S,Vn.4S,Vm.S[lane]</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..3]</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vqrdmlahq_laneq_s32(v128 a0, v128 a1, v128 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Vd.4H,Vn.4H,Vm.H[lane]</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..3]</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vqrdmlsh_lane_s16(v64 a0, v64 a1, v64 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Vd.8H,Vn.8H,Vm.H[lane]</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..3]</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vqrdmlshq_lane_s16(v128 a0, v128 a1, v64 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Vd.4H,Vn.4H,Vm.H[lane]</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..7]</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vqrdmlsh_laneq_s16(v64 a0, v64 a1, v128 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Vd.8H,Vn.8H,Vm.H[lane]</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..7]</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vqrdmlshq_laneq_s16(v128 a0, v128 a1, v128 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Vd.2S,Vn.2S,Vm.S[lane]</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..1]</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vqrdmlsh_lane_s32(v64 a0, v64 a1, v64 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Vd.4S,Vn.4S,Vm.S[lane]</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..1]</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vqrdmlshq_lane_s32(v128 a0, v128 a1, v64 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Vd.2S,Vn.2S,Vm.S[lane]</c></summary>
/// <param name="a0">64-bit vector a0</param>
/// <param name="a1">64-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..3]</param>
/// <returns>64-bit vector</returns>
[DebuggerStepThrough]
public static v64 vqrdmlsh_laneq_s32(v64 a0, v64 a1, v128 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Vd.4S,Vn.4S,Vm.S[lane]</c></summary>
/// <param name="a0">128-bit vector a0</param>
/// <param name="a1">128-bit vector a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..3]</param>
/// <returns>128-bit vector</returns>
[DebuggerStepThrough]
public static v128 vqrdmlshq_laneq_s32(v128 a0, v128 a1, v128 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Hd,Hn,Hm</c></summary>
/// <param name="a0">Int16 a0</param>
/// <param name="a1">Int16 a1</param>
/// <param name="a2">Int16 a2</param>
/// <returns>Int16</returns>
[DebuggerStepThrough]
public static Int16 vqrdmlahh_s16(Int16 a0, Int16 a1, Int16 a2)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Sd,Sn,Sm</c></summary>
/// <param name="a0">Int32 a0</param>
/// <param name="a1">Int32 a1</param>
/// <param name="a2">Int32 a2</param>
/// <returns>Int32</returns>
[DebuggerStepThrough]
public static Int32 vqrdmlahs_s32(Int32 a0, Int32 a1, Int32 a2)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Hd,Hn,Hm</c></summary>
/// <param name="a0">Int16 a0</param>
/// <param name="a1">Int16 a1</param>
/// <param name="a2">Int16 a2</param>
/// <returns>Int16</returns>
[DebuggerStepThrough]
public static Int16 vqrdmlshh_s16(Int16 a0, Int16 a1, Int16 a2)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Sd,Sn,Sm</c></summary>
/// <param name="a0">Int32 a0</param>
/// <param name="a1">Int32 a1</param>
/// <param name="a2">Int32 a2</param>
/// <returns>Int32</returns>
[DebuggerStepThrough]
public static Int32 vqrdmlshs_s32(Int32 a0, Int32 a1, Int32 a2)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Hd,Hn,Vm.H[lane]</c></summary>
/// <param name="a0">Int16 a0</param>
/// <param name="a1">Int16 a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..3]</param>
/// <returns>Int16</returns>
[DebuggerStepThrough]
public static Int16 vqrdmlahh_lane_s16(Int16 a0, Int16 a1, v64 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Hd,Hn,Vm.H[lane]</c></summary>
/// <param name="a0">Int16 a0</param>
/// <param name="a1">Int16 a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..7]</param>
/// <returns>Int16</returns>
[DebuggerStepThrough]
public static Int16 vqrdmlahh_laneq_s16(Int16 a0, Int16 a1, v128 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and accumulates the most significant half of the final results with the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLAH Sd,Sn,Vm.S[lane]</c></summary>
/// <param name="a0">Int32 a0</param>
/// <param name="a1">Int32 a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..1]</param>
/// <returns>Int32</returns>
[DebuggerStepThrough]
public static Int32 vqrdmlahs_lane_s32(Int32 a0, Int32 a1, v64 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Hd,Hn,Vm.H[lane]</c></summary>
/// <param name="a0">Int16 a0</param>
/// <param name="a1">Int16 a1</param>
/// <param name="a2">64-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..3]</param>
/// <returns>Int16</returns>
[DebuggerStepThrough]
public static Int16 vqrdmlshh_lane_s16(Int16 a0, Int16 a1, v64 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Hd,Hn,Vm.H[lane]</c></summary>
/// <param name="a0">Int16 a0</param>
/// <param name="a1">Int16 a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..7]</param>
/// <returns>Int16</returns>
[DebuggerStepThrough]
public static Int16 vqrdmlshh_laneq_s16(Int16 a0, Int16 a1, v128 a2, Int32 a3)
{
throw new NotImplementedException();
}
/// <summary>Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by element). This instruction multiplies the vector elements of the first source SIMD&amp;FP register with the value of a vector element of the second source SIMD&amp;FP register without saturating the multiply results, doubles the results, and subtracts the most significant half of the final results from the vector elements of the destination SIMD&amp;FP register. The results are rounded.If any of the results overflow, they are saturated. The cumulative saturation bit, FPSR.QC, is set if saturation occurs.Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.
/// <br/>Equivalent instruction: <c>SQRDMLSH Sd,Sn,Vm.S[lane]</c></summary>
/// <param name="a0">Int32 a0</param>
/// <param name="a1">Int32 a1</param>
/// <param name="a2">128-bit vector a2</param>
/// <param name="a3">Lane index to a2. Must be an immediate in the range of [0..3]</param>
/// <returns>Int32</returns>
[DebuggerStepThrough]
public static Int32 vqrdmlshs_lane_s32(Int32 a0, Int32 a1, v64 a2, Int32 a3)
{
throw new NotImplementedException();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 082593b719933f8b9f8feb40687d867e
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 05892f401645378395984f5ca02f11f1
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,328 @@
using System;
namespace Unity.Burst.Intrinsics
{
/// <summary>
/// Common intrinsics that are exposed across all Burst targets.
/// </summary>
public static class Common
{
/// <summary>
/// Hint that the current thread should pause.
///
/// In Burst compiled code this will map to platform specific
/// ways to hint that the current thread should be paused as
/// it is performing a calculation that would benefit from
/// not contending with other threads. Atomic operations in
/// tight loops (like spin-locks) can benefit from use of this
/// intrinsic.
///
/// - On x86 systems this maps to the `pause` instruction.
/// - On ARM systems this maps to the `yield` instruction.
///
/// Note that this is not an operating system level thread yield,
/// it only provides a hint to the CPU that the current thread can
/// afford to pause its execution temporarily.
/// </summary>
public static void Pause() { }
#if UNITY_BURST_EXPERIMENTAL_PREFETCH_INTRINSIC
public enum ReadWrite : int
{
Read = 0,
Write = 1,
}
public enum Locality : int
{
NoTemporalLocality = 0,
LowTemporalLocality = 1,
ModerateTemporalLocality = 2,
HighTemporalLocality = 3,
}
/// <summary>
/// Prefetch a pointer.
/// </summary>
/// <param name="v">The pointer to prefetch.</param>
/// <param name="rw">Whether the pointer will be used for reading or writing.</param>
/// <param name="locality">The cache locality of the pointer.</param>
public static unsafe void Prefetch(void* v, ReadWrite rw, Locality locality = Locality.HighTemporalLocality) { }
#endif
/// <summary>
/// Return the low half of the multiplication of two numbers, and the high part as an out parameter.
/// </summary>
/// <param name="x">A value to multiply.</param>
/// <param name="y">A value to multiply.</param>
/// <param name="high">The high-half of the multiplication result.</param>
/// <returns>The low-half of the multiplication result.</returns>
public static ulong umul128(ulong x, ulong y, out ulong high)
{
// Provide a software fallback for the cases Burst isn't being used.
// Split the inputs into high/low sections.
ulong xLo = (uint)x;
ulong xHi = x >> 32;
ulong yLo = (uint)y;
ulong yHi = y >> 32;
// We have to use 4 multiples to compute the full range of the result.
ulong hi = xHi * yHi;
ulong m1 = xHi * yLo;
ulong m2 = yHi * xLo;
ulong lo = xLo * yLo;
ulong m1Lo = (uint)m1;
ulong loHi = lo >> 32;
ulong m1Hi = m1 >> 32;
high = hi + m1Hi + ((loHi + m1Lo + m2) >> 32);
return x * y;
}
#if UNITY_BURST_EXPERIMENTAL_ATOMIC_INTRINSICS
/// <summary>
/// Bitwise and as an atomic operation.
/// </summary>
/// <param name="location">Where to atomically and the result into.</param>
/// <param name="value">The value to be combined.</param>
/// <returns>The original value in <paramref name="location" />.</returns>
/// <remarks>Using the return value of this intrinsic may result in worse code-generation on some platforms (a compare-exchange loop), rather than a single atomic instruction being generated.</remarks>
/// <seealso cref="https://docs.microsoft.com/en-us/dotnet/api/system.threading.interlocked.and"/>
public static int InterlockedAnd(ref int location, int value)
{
// Provide a software fallback for the cases Burst isn't being used.
var currentValue = System.Threading.Interlocked.Add(ref location, 0);
while (true)
{
var updatedValue = currentValue & value;
// If nothing would change by and'ing in our thing, bail out early.
if (updatedValue == currentValue)
{
return currentValue;
}
var newValue = System.Threading.Interlocked.CompareExchange(ref location, updatedValue, currentValue);
// If the original value was the same as the what we just got back from the compare exchange, it means our update succeeded.
if (newValue == currentValue)
{
return currentValue;
}
// Lastly update the last known good value of location and try again!
currentValue = newValue;
}
}
/// <summary>
/// Bitwise and as an atomic operation.
/// </summary>
/// <param name="location">Where to atomically and the result into.</param>
/// <param name="value">The value to be combined.</param>
/// <returns>The original value in <paramref name="location" />.</returns>
/// <remarks>Using the return value of this intrinsic may result in worse code-generation on some platforms (a compare-exchange loop), rather than a single atomic instruction being generated.</remarks>
/// <seealso cref="https://docs.microsoft.com/en-us/dotnet/api/system.threading.interlocked.and"/>
public static uint InterlockedAnd(ref uint location, uint value)
{
unsafe
{
ref int locationAsInt = ref Unsafe.AsRef<int>(Unsafe.AsPointer(ref location));
int valueAsInt = (int)value;
return (uint)InterlockedAnd(ref locationAsInt, valueAsInt);
}
}
/// <summary>
/// Bitwise and as an atomic operation.
/// </summary>
/// <param name="location">Where to atomically and the result into.</param>
/// <param name="value">The value to be combined.</param>
/// <returns>The original value in <paramref name="location" />.</returns>
/// <remarks>Using the return value of this intrinsic may result in worse code-generation on some platforms (a compare-exchange loop), rather than a single atomic instruction being generated.</remarks>
/// <seealso cref="https://docs.microsoft.com/en-us/dotnet/api/system.threading.interlocked.and"/>
public static long InterlockedAnd(ref long location, long value)
{
// Provide a software fallback for the cases Burst isn't being used.
var currentValue = System.Threading.Interlocked.Read(ref location);
while (true)
{
var updatedValue = currentValue & value;
// If nothing would change by and'ing in our thing, bail out early.
if (updatedValue == currentValue)
{
return currentValue;
}
var newValue = System.Threading.Interlocked.CompareExchange(ref location, updatedValue, currentValue);
// If the original value was the same as the what we just got back from the compare exchange, it means our update succeeded.
if (newValue == currentValue)
{
return currentValue;
}
// Lastly update the last known good value of location and try again!
currentValue = newValue;
}
}
/// <summary>
/// Bitwise and as an atomic operation.
/// </summary>
/// <param name="location">Where to atomically and the result into.</param>
/// <param name="value">The value to be combined.</param>
/// <returns>The original value in <paramref name="location" />.</returns>
/// <remarks>Using the return value of this intrinsic may result in worse code-generation on some platforms (a compare-exchange loop), rather than a single atomic instruction being generated.</remarks>
/// <seealso cref="https://docs.microsoft.com/en-us/dotnet/api/system.threading.interlocked.and"/>
public static ulong InterlockedAnd(ref ulong location, ulong value)
{
unsafe
{
ref long locationAsInt = ref Unsafe.AsRef<long>(Unsafe.AsPointer(ref location));
long valueAsInt = (long)value;
return (ulong)InterlockedAnd(ref locationAsInt, valueAsInt);
}
}
/// <summary>
/// Bitwise or as an atomic operation.
/// </summary>
/// <param name="location">Where to atomically or the result into.</param>
/// <param name="value">The value to be combined.</param>
/// <returns>The original value in <paramref name="location" />.</returns>
/// <remarks>Using the return value of this intrinsic may result in worse code-generation on some platforms (a compare-exchange loop), rather than a single atomic instruction being generated.</remarks>
/// <seealso cref="https://docs.microsoft.com/en-us/dotnet/api/system.threading.interlocked.or"/>
public static int InterlockedOr(ref int location, int value)
{
// Provide a software fallback for the cases Burst isn't being used.
var currentValue = System.Threading.Interlocked.Add(ref location, 0);
while (true)
{
var updatedValue = currentValue | value;
// If nothing would change by or'ing in our thing, bail out early.
if (updatedValue == currentValue)
{
return currentValue;
}
var newValue = System.Threading.Interlocked.CompareExchange(ref location, updatedValue, currentValue);
// If the original value was the same as the what we just got back from the compare exchange, it means our update succeeded.
if (newValue == currentValue)
{
return currentValue;
}
// Lastly update the last known good value of location and try again!
currentValue = newValue;
}
}
/// <summary>
/// Bitwise or as an atomic operation.
/// </summary>
/// <param name="location">Where to atomically or the result into.</param>
/// <param name="value">The value to be combined.</param>
/// <returns>The original value in <paramref name="location" />.</returns>
/// <remarks>Using the return value of this intrinsic may result in worse code-generation on some platforms (a compare-exchange loop), rather than a single atomic instruction being generated.</remarks>
/// <seealso cref="https://docs.microsoft.com/en-us/dotnet/api/system.threading.interlocked.or"/>
public static uint InterlockedOr(ref uint location, uint value)
{
unsafe
{
ref int locationAsInt = ref Unsafe.AsRef<int>(Unsafe.AsPointer(ref location));
int valueAsInt = (int)value;
return (uint)InterlockedOr(ref locationAsInt, valueAsInt);
}
}
/// <summary>
/// Bitwise or as an atomic operation.
/// </summary>
/// <param name="location">Where to atomically or the result into.</param>
/// <param name="value">The value to be combined.</param>
/// <returns>The original value in <paramref name="location" />.</returns>
/// <remarks>Using the return value of this intrinsic may result in worse code-generation on some platforms (a compare-exchange loop), rather than a single atomic instruction being generated.</remarks>
/// <seealso cref="https://docs.microsoft.com/en-us/dotnet/api/system.threading.interlocked.or"/>
public static long InterlockedOr(ref long location, long value)
{
// Provide a software fallback for the cases Burst isn't being used.
var currentValue = System.Threading.Interlocked.Read(ref location);
while (true)
{
var updatedValue = currentValue | value;
// If nothing would change by or'ing in our thing, bail out early.
if (updatedValue == currentValue)
{
return currentValue;
}
var newValue = System.Threading.Interlocked.CompareExchange(ref location, updatedValue, currentValue);
// If the original value was the same as the what we just got back from the compare exchange, it means our update succeeded.
if (newValue == currentValue)
{
return currentValue;
}
// Lastly update the last known good value of location and try again!
currentValue = newValue;
}
}
/// <summary>
/// Bitwise or as an atomic operation.
/// </summary>
/// <param name="location">Where to atomically or the result into.</param>
/// <param name="value">The value to be combined.</param>
/// <returns>The original value in <paramref name="location" />.</returns>
/// <remarks>Using the return value of this intrinsic may result in worse code-generation on some platforms (a compare-exchange loop), rather than a single atomic instruction being generated.</remarks>
/// <seealso cref="https://docs.microsoft.com/en-us/dotnet/api/system.threading.interlocked.or"/>
public static ulong InterlockedOr(ref ulong location, ulong value)
{
unsafe
{
ref long locationAsInt = ref Unsafe.AsRef<long>(Unsafe.AsPointer(ref location));
long valueAsInt = (long)value;
return (ulong)InterlockedOr(ref locationAsInt, valueAsInt);
}
}
#endif
}
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
[BurstRuntime.Preserve]
// expose the type to btests via Unity.Burst.dll
#if BURST_INTERNAL
public
#else
internal
#endif
sealed class BurstTargetCpuAttribute : Attribute
{
public BurstTargetCpuAttribute(BurstTargetCpu TargetCpu)
{
this.TargetCpu = TargetCpu;
}
public readonly BurstTargetCpu TargetCpu;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5ac9520c05323eada8615cfe2d48e949
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,426 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Unity.Burst.Intrinsics
{
internal unsafe class V64DebugView
{
v64 m_Value;
public V64DebugView(v64 value)
{
m_Value = value;
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe byte[] Byte
{
get
{
return new byte[]
{
m_Value.Byte0, m_Value.Byte1, m_Value.Byte2, m_Value.Byte3,
m_Value.Byte4, m_Value.Byte5, m_Value.Byte6, m_Value.Byte7,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe sbyte[] SByte
{
get
{
return new sbyte[]
{
m_Value.SByte0, m_Value.SByte1, m_Value.SByte2, m_Value.SByte3,
m_Value.SByte4, m_Value.SByte5, m_Value.SByte6, m_Value.SByte7,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe ushort[] UShort
{
get
{
return new ushort[]
{
m_Value.UShort0, m_Value.UShort1, m_Value.UShort2, m_Value.UShort3,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe short[] SShort
{
get
{
return new short[]
{
m_Value.SShort0, m_Value.SShort1, m_Value.SShort2, m_Value.SShort3,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe uint[] UInt
{
get
{
return new uint[]
{
m_Value.UInt0, m_Value.UInt1,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe int[] SInt
{
get
{
return new int[]
{
m_Value.SInt0, m_Value.SInt1,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe float[] Float
{
get
{
return new float[]
{
m_Value.Float0, m_Value.Float1,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe long[] SLong
{
get
{
return new long[]
{
m_Value.SLong0,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe ulong[] ULong
{
get
{
return new ulong[]
{
m_Value.ULong0,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe double[] Double
{
get
{
return new double[]
{
m_Value.Double0,
};
}
}
}
internal unsafe class V128DebugView
{
v128 m_Value;
public V128DebugView(v128 value)
{
m_Value = value;
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe byte[] Byte
{
get
{
return new byte[]
{
m_Value.Byte0, m_Value.Byte1, m_Value.Byte2, m_Value.Byte3,
m_Value.Byte4, m_Value.Byte5, m_Value.Byte6, m_Value.Byte7,
m_Value.Byte8, m_Value.Byte9, m_Value.Byte10, m_Value.Byte11,
m_Value.Byte12, m_Value.Byte13, m_Value.Byte14, m_Value.Byte15,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe sbyte[] SByte
{
get
{
return new sbyte[]
{
m_Value.SByte0, m_Value.SByte1, m_Value.SByte2, m_Value.SByte3,
m_Value.SByte4, m_Value.SByte5, m_Value.SByte6, m_Value.SByte7,
m_Value.SByte8, m_Value.SByte9, m_Value.SByte10, m_Value.SByte11,
m_Value.SByte12, m_Value.SByte13, m_Value.SByte14, m_Value.SByte15,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe ushort[] UShort
{
get
{
return new ushort[]
{
m_Value.UShort0, m_Value.UShort1, m_Value.UShort2, m_Value.UShort3,
m_Value.UShort4, m_Value.UShort5, m_Value.UShort6, m_Value.UShort7,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe short[] SShort
{
get
{
return new short[]
{
m_Value.SShort0, m_Value.SShort1, m_Value.SShort2, m_Value.SShort3,
m_Value.SShort4, m_Value.SShort5, m_Value.SShort6, m_Value.SShort7,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe uint[] UInt
{
get
{
return new uint[]
{
m_Value.UInt0, m_Value.UInt1, m_Value.UInt2, m_Value.UInt3,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe int[] SInt
{
get
{
return new int[]
{
m_Value.SInt0, m_Value.SInt1, m_Value.SInt2, m_Value.SInt3,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe float[] Float
{
get
{
return new float[]
{
m_Value.Float0, m_Value.Float1, m_Value.Float2, m_Value.Float3,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe long[] SLong
{
get
{
return new long[]
{
m_Value.SLong0, m_Value.SLong1,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe ulong[] ULong
{
get
{
return new ulong[]
{
m_Value.ULong0, m_Value.ULong1,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe double[] Double
{
get
{
return new double[]
{
m_Value.Double0, m_Value.Double1,
};
}
}
}
internal unsafe class V256DebugView
{
v256 m_Value;
public V256DebugView(v256 value)
{
m_Value = value;
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe byte[] Byte
{
get
{
return new byte[]
{
m_Value.Byte0, m_Value.Byte1, m_Value.Byte2, m_Value.Byte3,
m_Value.Byte4, m_Value.Byte5, m_Value.Byte6, m_Value.Byte7,
m_Value.Byte8, m_Value.Byte9, m_Value.Byte10, m_Value.Byte11,
m_Value.Byte12, m_Value.Byte13, m_Value.Byte14, m_Value.Byte15,
m_Value.Byte16, m_Value.Byte17, m_Value.Byte18, m_Value.Byte19,
m_Value.Byte20, m_Value.Byte21, m_Value.Byte22, m_Value.Byte23,
m_Value.Byte24, m_Value.Byte25, m_Value.Byte26, m_Value.Byte27,
m_Value.Byte28, m_Value.Byte29, m_Value.Byte30, m_Value.Byte31,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe sbyte[] SByte
{
get
{
return new sbyte[]
{
m_Value.SByte0, m_Value.SByte1, m_Value.SByte2, m_Value.SByte3,
m_Value.SByte4, m_Value.SByte5, m_Value.SByte6, m_Value.SByte7,
m_Value.SByte8, m_Value.SByte9, m_Value.SByte10, m_Value.SByte11,
m_Value.SByte12, m_Value.SByte13, m_Value.SByte14, m_Value.SByte15,
m_Value.SByte16, m_Value.SByte17, m_Value.SByte18, m_Value.SByte19,
m_Value.SByte20, m_Value.SByte21, m_Value.SByte22, m_Value.SByte23,
m_Value.SByte24, m_Value.SByte25, m_Value.SByte26, m_Value.SByte27,
m_Value.SByte28, m_Value.SByte29, m_Value.SByte30, m_Value.SByte31,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe ushort[] UShort
{
get
{
return new ushort[]
{
m_Value.UShort0, m_Value.UShort1, m_Value.UShort2, m_Value.UShort3,
m_Value.UShort4, m_Value.UShort5, m_Value.UShort6, m_Value.UShort7,
m_Value.UShort8, m_Value.UShort9, m_Value.UShort10, m_Value.UShort11,
m_Value.UShort12, m_Value.UShort13, m_Value.UShort14, m_Value.UShort15,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe short[] SShort
{
get
{
return new short[]
{
m_Value.SShort0, m_Value.SShort1, m_Value.SShort2, m_Value.SShort3,
m_Value.SShort4, m_Value.SShort5, m_Value.SShort6, m_Value.SShort7,
m_Value.SShort8, m_Value.SShort9, m_Value.SShort10, m_Value.SShort11,
m_Value.SShort12, m_Value.SShort13, m_Value.SShort14, m_Value.SShort15,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe uint[] UInt
{
get
{
return new uint[]
{
m_Value.UInt0, m_Value.UInt1, m_Value.UInt2, m_Value.UInt3,
m_Value.UInt4, m_Value.UInt5, m_Value.UInt6, m_Value.UInt7,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe int[] SInt
{
get
{
return new int[]
{
m_Value.SInt0, m_Value.SInt1, m_Value.SInt2, m_Value.SInt3,
m_Value.SInt4, m_Value.SInt5, m_Value.SInt6, m_Value.SInt7,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe float[] Float
{
get
{
return new float[]
{
m_Value.Float0, m_Value.Float1, m_Value.Float2, m_Value.Float3,
m_Value.Float4, m_Value.Float5, m_Value.Float6, m_Value.Float7,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe long[] SLong
{
get
{
return new long[]
{
m_Value.SLong0, m_Value.SLong1, m_Value.SLong2, m_Value.SLong3,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe ulong[] ULong
{
get
{
return new ulong[]
{
m_Value.ULong0, m_Value.ULong1, m_Value.ULong2, m_Value.ULong3,
};
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public unsafe double[] Double
{
get
{
return new double[]
{
m_Value.Double0, m_Value.Double1, m_Value.Double2, m_Value.Double3,
};
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4a0e9007c9c8384893d917e1f0d6e5d9
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,140 @@
#if BURST_INTERNAL || UNITY_BURST_EXPERIMENTAL_NEON_INTRINSICS
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using static Unity.Burst.Intrinsics.Arm.Neon;
using static Unity.Burst.Intrinsics.X86.F16C;
namespace Unity.Burst.Intrinsics
{
/// <summary>
/// Represents a 16-bit floating point value (half precision)
/// Warning: this type may not be natively supported by your hardware, or its usage may be suboptimal
/// </summary>
public readonly struct f16 : System.IEquatable<f16>
{
/// <summary>
/// The container for the actual 16-bit half precision floating point value
/// </summary>
private readonly ushort value;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static uint f32tof16(float x)
{
if (IsF16CSupported)
{
var v = new v128();
v.Float0 = x;
var result = cvtps_ph(v, (int)X86.RoundingMode.FROUND_TRUNC_NOEXC);
return result.UShort0;
}
else if (IsNeonHalfFPSupported)
{
var v = new v128();
v.Float0 = x;
var result = vcvt_f16_f32(v);
return result.UShort0;
}
// Managed fallback
const int infinity_32 = 255 << 23;
const uint msk = 0x7FFFF000u;
uint ux = asuint(x);
uint uux = ux & msk;
uint h = (uint)(asuint(min(asfloat(uux) * 1.92592994e-34f, 260042752.0f)) + 0x1000) >> 13; // Clamp to signed infinity if overflowed
h = select(h,
select(0x7c00u, 0x7e00u, (int)uux > infinity_32),
(int)uux >= infinity_32); // NaN->qNaN and Inf->Inf
return h | (ux & ~msk) >> 16;
}
/// <summary>Returns the bit pattern of a float as a uint.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static uint asuint(float x) { return (uint)asint(x); }
/// <summary>Returns the minimum of two float values.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static float min(float x, float y) { return float.IsNaN(y) || x < y ? x : y; }
/// <summary>Returns b if c is true, a otherwise.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static uint select(uint a, uint b, bool c) { return c ? b : a; }
/// <summary>Returns the bit pattern of a uint as a float.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static float asfloat(uint x) { return asfloat((int)x); }
[StructLayout(LayoutKind.Explicit)]
private struct IntFloatUnion
{
[FieldOffset(0)]
public int intValue;
[FieldOffset(0)]
public float floatValue;
}
/// <summary>Returns the bit pattern of an int as a float.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static float asfloat(int x)
{
IntFloatUnion u;
u.floatValue = 0;
u.intValue = x;
return u.floatValue;
}
/// <summary>Returns the bit pattern of a float as an int.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int asint(float x)
{
IntFloatUnion u;
u.intValue = 0;
u.floatValue = x;
return u.intValue;
}
/// <summary>Constructs a half value from a half value.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public f16(f16 x)
{
value = x.value;
}
/// <summary>Constructs a half value from a float value.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public f16(float v)
{
value = (ushort)f32tof16(v);
}
/// <summary>Returns whether two f16 values are equal.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(f16 lhs, f16 rhs)
{
return lhs.value == rhs.value;
}
/// <summary>Returns whether two f16 values are different.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(f16 lhs, f16 rhs)
{
return lhs.value != rhs.value;
}
/// <summary>Returns true if the f16 is equal to a given f16, false otherwise.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(f16 rhs)
{
return value == rhs.value;
}
/// <summary>Returns true if the half is equal to a given half, false otherwise.</summary>
public override bool Equals(object o) { return Equals((f16)o); }
/// <summary>Returns a hash code for the half.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode() { return (int)value; }
}
}
#endif // BURST_INTERNAL || UNITY_BURST_EXPERIMENTAL_NEON_INTRINSICS

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8cf029a460b7321e8496e8d836e8e899
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,808 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Unity.Burst.Intrinsics
{
/// <summary>
/// Represents a 128-bit SIMD value
/// </summary>
[StructLayout(LayoutKind.Explicit)]
[DebuggerTypeProxy(typeof(V128DebugView))]
public struct v128
{
/// <summary>
/// Get the 0th Byte of the vector
/// </summary>
[FieldOffset(0)] public byte Byte0;
/// <summary>
/// Get the 1st Byte of the vector
/// </summary>
[FieldOffset(1)] public byte Byte1;
/// <summary>
/// Get the 2nd Byte of the vector
/// </summary>
[FieldOffset(2)] public byte Byte2;
/// <summary>
/// Get the 3rd Byte of the vector
/// </summary>
[FieldOffset(3)] public byte Byte3;
/// <summary>
/// Get the 4th Byte of the vector
/// </summary>
[FieldOffset(4)] public byte Byte4;
/// <summary>
/// Get the 5th Byte of the vector
/// </summary>
[FieldOffset(5)] public byte Byte5;
/// <summary>
/// Get the 6th Byte of the vector
/// </summary>
[FieldOffset(6)] public byte Byte6;
/// <summary>
/// Get the 7th Byte of the vector
/// </summary>
[FieldOffset(7)] public byte Byte7;
/// <summary>
/// Get the 8th Byte of the vector
/// </summary>
[FieldOffset(8)] public byte Byte8;
/// <summary>
/// Get the 9th Byte of the vector
/// </summary>
[FieldOffset(9)] public byte Byte9;
/// <summary>
/// Get the 10th Byte of the vector
/// </summary>
[FieldOffset(10)] public byte Byte10;
/// <summary>
/// Get the 11th Byte of the vector
/// </summary>
[FieldOffset(11)] public byte Byte11;
/// <summary>
/// Get the 12 Byte of the vector
/// </summary>
[FieldOffset(12)] public byte Byte12;
/// <summary>
/// Get the 13th Byte of the vector
/// </summary>
[FieldOffset(13)] public byte Byte13;
/// <summary>
/// Get the 14th Byte of the vector
/// </summary>
[FieldOffset(14)] public byte Byte14;
/// <summary>
/// Get the 15th Byte of the vector
/// </summary>
[FieldOffset(15)] public byte Byte15;
/// <summary>
/// Get the 0th SByte of the vector
/// </summary>
[FieldOffset(0)] public sbyte SByte0;
/// <summary>
/// Get the 1st SByte of the vector
/// </summary>
[FieldOffset(1)] public sbyte SByte1;
/// <summary>
/// Get the 2nd SByte of the vector
/// </summary>
[FieldOffset(2)] public sbyte SByte2;
/// <summary>
/// Get the 3rd SByte of the vector
/// </summary>
[FieldOffset(3)] public sbyte SByte3;
/// <summary>
/// Get the 4th SByte of the vector
/// </summary>
[FieldOffset(4)] public sbyte SByte4;
/// <summary>
/// Get the 5th SByte of the vector
/// </summary>
[FieldOffset(5)] public sbyte SByte5;
/// <summary>
/// Get the 6th SByte of the vector
/// </summary>
[FieldOffset(6)] public sbyte SByte6;
/// <summary>
/// Get the 7th SByte of the vector
/// </summary>
[FieldOffset(7)] public sbyte SByte7;
/// <summary>
/// Get the 8th SByte of the vector
/// </summary>
[FieldOffset(8)] public sbyte SByte8;
/// <summary>
/// Get the 9th SByte of the vector
/// </summary>
[FieldOffset(9)] public sbyte SByte9;
/// <summary>
/// Get the 10th SByte of the vector
/// </summary>
[FieldOffset(10)] public sbyte SByte10;
/// <summary>
/// Get the 11th SByte of the vector
/// </summary>
[FieldOffset(11)] public sbyte SByte11;
/// <summary>
/// Get the 12th SByte of the vector
/// </summary>
[FieldOffset(12)] public sbyte SByte12;
/// <summary>
/// Get the 13th SByte of the vector
/// </summary>
[FieldOffset(13)] public sbyte SByte13;
/// <summary>
/// Get the 14th SByte of the vector
/// </summary>
[FieldOffset(14)] public sbyte SByte14;
/// <summary>
/// Get the 15th SByte of the vector
/// </summary>
[FieldOffset(15)] public sbyte SByte15;
/// <summary>
/// Get the 0th UShort of the vector
/// </summary>
[FieldOffset(0)] public ushort UShort0;
/// <summary>
/// Get the 1st UShort of the vector
/// </summary>
[FieldOffset(2)] public ushort UShort1;
/// <summary>
/// Get the 2nd UShort of the vector
/// </summary>
[FieldOffset(4)] public ushort UShort2;
/// <summary>
/// Get the 3rd UShort of the vector
/// </summary>
[FieldOffset(6)] public ushort UShort3;
/// <summary>
/// Get the 4th UShort of the vector
/// </summary>
[FieldOffset(8)] public ushort UShort4;
/// <summary>
/// Get the 5th UShort of the vector
/// </summary>
[FieldOffset(10)] public ushort UShort5;
/// <summary>
/// Get the 6th UShort of the vector
/// </summary>
[FieldOffset(12)] public ushort UShort6;
/// <summary>
/// Get the 7th UShort of the vector
/// </summary>
[FieldOffset(14)] public ushort UShort7;
/// <summary>
/// Get the 0th SShort of the vector
/// </summary>
[FieldOffset(0)] public short SShort0;
/// <summary>
/// Get the 1st UShort of the vector
/// </summary>
[FieldOffset(2)] public short SShort1;
/// <summary>
/// Get the 2nd UShort of the vector
/// </summary>
[FieldOffset(4)] public short SShort2;
/// <summary>
/// Get the 3rd UShort of the vector
/// </summary>
[FieldOffset(6)] public short SShort3;
/// <summary>
/// Get the 4th UShort of the vector
/// </summary>
[FieldOffset(8)] public short SShort4;
/// <summary>
/// Get the 5th UShort of the vector
/// </summary>
[FieldOffset(10)] public short SShort5;
/// <summary>
/// Get the 6th UShort of the vector
/// </summary>
[FieldOffset(12)] public short SShort6;
/// <summary>
/// Get the 7th UShort of the vector
/// </summary>
[FieldOffset(14)] public short SShort7;
#if BURST_INTERNAL || UNITY_BURST_EXPERIMENTAL_NEON_INTRINSICS
/// <summary>
/// Get the 0th f16 of the vector
/// </summary>
[FieldOffset(0)] public f16 Half0;
/// <summary>
/// Get the 1st f16 of the vector
/// </summary>
[FieldOffset(2)] public f16 Half1;
/// <summary>
/// Get the 2nd f16 of the vector
/// </summary>
[FieldOffset(4)] public f16 Half2;
/// <summary>
/// Get the 3rd f16 of the vector
/// </summary>
[FieldOffset(6)] public f16 Half3;
/// <summary>
/// Get the 4th f16 of the vector
/// </summary>
[FieldOffset(8)] public f16 Half4;
/// <summary>
/// Get the 5th f16 of the vector
/// </summary>
[FieldOffset(10)] public f16 Half5;
/// <summary>
/// Get the 6th f16 of the vector
/// </summary>
[FieldOffset(12)] public f16 Half6;
/// <summary>
/// Get the 7th f16 of the vector
/// </summary>
[FieldOffset(14)] public f16 Half7;
#endif // BURST_INTERNAL || UNITY_BURST_EXPERIMENTAL_NEON_INTRINSICS
/// <summary>
/// Get the 0th UInt of the vector
/// </summary>
[FieldOffset(0)] public uint UInt0;
/// <summary>
/// Get the 1st UInt of the vector
/// </summary>
[FieldOffset(4)] public uint UInt1;
/// <summary>
/// Get the 2nd UInt of the vector
/// </summary>
[FieldOffset(8)] public uint UInt2;
/// <summary>
/// Get the 3rd UInt of the vector
/// </summary>
[FieldOffset(12)] public uint UInt3;
/// <summary>
/// Get the 0th SInt of the vector
/// </summary>
[FieldOffset(0)] public int SInt0;
/// <summary>
/// Get the 1st SInt of the vector
/// </summary>
[FieldOffset(4)] public int SInt1;
/// <summary>
/// Get the 2nd SInt of the vector
/// </summary>
[FieldOffset(8)] public int SInt2;
/// <summary>
/// Get the 3rd SInt of the vector
/// </summary>
[FieldOffset(12)] public int SInt3;
/// <summary>
/// Get the 0th ULong of the vector
/// </summary>
[FieldOffset(0)] public ulong ULong0;
/// <summary>
/// Get the 1st ULong of the vector
/// </summary>
[FieldOffset(8)] public ulong ULong1;
/// <summary>
/// Get the 0th SLong of the vector
/// </summary>
[FieldOffset(0)] public long SLong0;
/// <summary>
/// Get the 1st SLong of the vector
/// </summary>
[FieldOffset(8)] public long SLong1;
/// <summary>
/// Get the 0th Float of the vector
/// </summary>
[FieldOffset(0)] public float Float0;
/// <summary>
/// Get the 1st Float of the vector
/// </summary>
[FieldOffset(4)] public float Float1;
/// <summary>
/// Get the 2nd Float of the vector
/// </summary>
[FieldOffset(8)] public float Float2;
/// <summary>
/// Get the 3rd Float of the vector
/// </summary>
[FieldOffset(12)] public float Float3;
/// <summary>
/// Get the 0th Double of the vector
/// </summary>
[FieldOffset(0)] public double Double0;
/// <summary>
/// Get the 1st Double of the vector
/// </summary>
[FieldOffset(8)] public double Double1;
/// <summary>
/// Get the low half of the vector
/// </summary>
[FieldOffset(0)] public v64 Lo64;
/// <summary>
/// Get the high half of the vector
/// </summary>
[FieldOffset(8)] public v64 Hi64;
/// <summary>
/// Splat a single byte across the v128
/// </summary>
/// <param name="b">Splatted byte.</param>
public v128(byte b)
{
this = default(v128);
Byte0 = Byte1 = Byte2 = Byte3 = Byte4 = Byte5 = Byte6 = Byte7 = Byte8 = Byte9 = Byte10 = Byte11 = Byte12 = Byte13 = Byte14 = Byte15 = b;
}
/// <summary>
/// Initialize the v128 with 16 bytes
/// </summary>
/// <param name="a">byte a.</param>
/// <param name="b">byte b.</param>
/// <param name="c">byte c.</param>
/// <param name="d">byte d.</param>
/// <param name="e">byte e.</param>
/// <param name="f">byte f.</param>
/// <param name="g">byte g.</param>
/// <param name="h">byte h.</param>
/// <param name="i">byte i.</param>
/// <param name="j">byte j.</param>
/// <param name="k">byte k.</param>
/// <param name="l">byte l.</param>
/// <param name="m">byte m.</param>
/// <param name="n">byte n.</param>
/// <param name="o">byte o.</param>
/// <param name="p">byte p.</param>
public v128(
byte a, byte b, byte c, byte d,
byte e, byte f, byte g, byte h,
byte i, byte j, byte k, byte l,
byte m, byte n, byte o, byte p)
{
this = default(v128);
Byte0 = a;
Byte1 = b;
Byte2 = c;
Byte3 = d;
Byte4 = e;
Byte5 = f;
Byte6 = g;
Byte7 = h;
Byte8 = i;
Byte9 = j;
Byte10 = k;
Byte11 = l;
Byte12 = m;
Byte13 = n;
Byte14 = o;
Byte15 = p;
}
/// <summary>
/// Splat a single sbyte across the v128
/// </summary>
/// <param name="b">Splatted sbyte.</param>
public v128(sbyte b)
{
this = default(v128);
SByte0 = SByte1 = SByte2 = SByte3 = SByte4 = SByte5 = SByte6 = SByte7 = SByte8 = SByte9 = SByte10 = SByte11 = SByte12 = SByte13 = SByte14 = SByte15 = b;
}
/// <summary>
/// Initialize the v128 with 16 sbytes
/// </summary>
/// <param name="a">sbyte a.</param>
/// <param name="b">sbyte b.</param>
/// <param name="c">sbyte c.</param>
/// <param name="d">sbyte d.</param>
/// <param name="e">sbyte e.</param>
/// <param name="f">sbyte f.</param>
/// <param name="g">sbyte g.</param>
/// <param name="h">sbyte h.</param>
/// <param name="i">sbyte i.</param>
/// <param name="j">sbyte j.</param>
/// <param name="k">sbyte k.</param>
/// <param name="l">sbyte l.</param>
/// <param name="m">sbyte m.</param>
/// <param name="n">sbyte n.</param>
/// <param name="o">sbyte o.</param>
/// <param name="p">sbyte p.</param>
public v128(
sbyte a, sbyte b, sbyte c, sbyte d,
sbyte e, sbyte f, sbyte g, sbyte h,
sbyte i, sbyte j, sbyte k, sbyte l,
sbyte m, sbyte n, sbyte o, sbyte p)
{
this = default(v128);
SByte0 = a;
SByte1 = b;
SByte2 = c;
SByte3 = d;
SByte4 = e;
SByte5 = f;
SByte6 = g;
SByte7 = h;
SByte8 = i;
SByte9 = j;
SByte10 = k;
SByte11 = l;
SByte12 = m;
SByte13 = n;
SByte14 = o;
SByte15 = p;
}
/// <summary>
/// Splat a single short across the v128
/// </summary>
/// <param name="v">Splatted short.</param>
public v128(short v)
{
this = default(v128);
SShort0 = SShort1 = SShort2 = SShort3 = SShort4 = SShort5 = SShort6 = SShort7 = v;
}
/// <summary>
/// Initialize the v128 with 8 shorts
/// </summary>
/// <param name="a">short a.</param>
/// <param name="b">short b.</param>
/// <param name="c">short c.</param>
/// <param name="d">short d.</param>
/// <param name="e">short e.</param>
/// <param name="f">short f.</param>
/// <param name="g">short g.</param>
/// <param name="h">short h.</param>
public v128(short a, short b, short c, short d, short e, short f, short g, short h)
{
this = default(v128);
SShort0 = a;
SShort1 = b;
SShort2 = c;
SShort3 = d;
SShort4 = e;
SShort5 = f;
SShort6 = g;
SShort7 = h;
}
/// <summary>
/// Splat a single ushort across the v128
/// </summary>
/// <param name="v">Splatted ushort.</param>
public v128(ushort v)
{
this = default(v128);
UShort0 = UShort1 = UShort2 = UShort3 = UShort4 = UShort5 = UShort6 = UShort7 = v;
}
/// <summary>
/// Initialize the v128 with 8 ushorts
/// </summary>
/// <param name="a">ushort a.</param>
/// <param name="b">ushort b.</param>
/// <param name="c">ushort c.</param>
/// <param name="d">ushort d.</param>
/// <param name="e">ushort e.</param>
/// <param name="f">ushort f.</param>
/// <param name="g">ushort g.</param>
/// <param name="h">ushort h.</param>
public v128(ushort a, ushort b, ushort c, ushort d, ushort e, ushort f, ushort g, ushort h)
{
this = default(v128);
UShort0 = a;
UShort1 = b;
UShort2 = c;
UShort3 = d;
UShort4 = e;
UShort5 = f;
UShort6 = g;
UShort7 = h;
}
#if BURST_INTERNAL || UNITY_BURST_EXPERIMENTAL_NEON_INTRINSICS
/// <summary>
/// Splat a single f16 across the v128
/// </summary>
/// <param name="v">Splatted f16.</param>
public v128(f16 v)
{
this = default(v128);
Half0 = Half1 = Half2 = Half3 = Half4 = Half5 = Half6 = Half7 = v;
}
/// <summary>
/// Initialize the v128 with 8 half's
/// </summary>
/// <param name="a">f16 a.</param>
/// <param name="b">f16 b.</param>
/// <param name="c">f16 c.</param>
/// <param name="d">f16 d.</param>
/// <param name="e">f16 e.</param>
/// <param name="f">f16 f.</param>
/// <param name="g">f16 g.</param>
/// <param name="h">f16 h.</param>
public v128(f16 a, f16 b, f16 c, f16 d, f16 e, f16 f, f16 g, f16 h)
{
this = default(v128);
Half0 = a;
Half1 = b;
Half2 = c;
Half3 = d;
Half4 = e;
Half5 = f;
Half6 = g;
Half7 = h;
}
#endif // BURST_INTERNAL || UNITY_BURST_EXPERIMENTAL_NEON_INTRINSICS
/// <summary>
/// Splat a single int across the v128
/// </summary>
/// <param name="v">Splatted int.</param>
public v128(int v)
{
this = default(v128);
SInt0 = SInt1 = SInt2 = SInt3 = v;
}
/// <summary>
/// Initialize the v128 with 4 ints
/// </summary>
/// <param name="a">int a.</param>
/// <param name="b">int b.</param>
/// <param name="c">int c.</param>
/// <param name="d">int d.</param>
public v128(int a, int b, int c, int d)
{
this = default(v128);
SInt0 = a;
SInt1 = b;
SInt2 = c;
SInt3 = d;
}
/// <summary>
/// Splat a single uint across the v128
/// </summary>
/// <param name="v">Splatted uint.</param>
public v128(uint v)
{
this = default(v128);
UInt0 = UInt1 = UInt2 = UInt3 = v;
}
/// <summary>
/// Initialize the v128 with 4 uints
/// </summary>
/// <param name="a">uint a.</param>
/// <param name="b">uint b.</param>
/// <param name="c">uint c.</param>
/// <param name="d">uint d.</param>
public v128(uint a, uint b, uint c, uint d)
{
this = default(v128);
UInt0 = a;
UInt1 = b;
UInt2 = c;
UInt3 = d;
}
/// <summary>
/// Splat a single float across the v128
/// </summary>
/// <param name="f">Splatted float.</param>
public v128(float f)
{
this = default(v128);
Float0 = Float1 = Float2 = Float3 = f;
}
/// <summary>
/// Initialize the v128 with 4 floats
/// </summary>
/// <param name="a">float a.</param>
/// <param name="b">float b.</param>
/// <param name="c">float c.</param>
/// <param name="d">float d.</param>
public v128(float a, float b, float c, float d)
{
this = default(v128);
Float0 = a;
Float1 = b;
Float2 = c;
Float3 = d;
}
/// <summary>
/// Splat a single double across the v128
/// </summary>
/// <param name="f">Splatted double.</param>
public v128(double f)
{
this = default(v128);
Double0 = Double1 = f;
}
/// <summary>
/// Initialize the v128 with 2 doubles
/// </summary>
/// <param name="a">double a.</param>
/// <param name="b">double b.</param>
public v128(double a, double b)
{
this = default(v128);
Double0 = a;
Double1 = b;
}
/// <summary>
/// Splat a single long across the v128
/// </summary>
/// <param name="f">Splatted long.</param>
public v128(long f)
{
this = default(v128);
SLong0 = SLong1 = f;
}
/// <summary>
/// Initialize the v128 with 2 longs
/// </summary>
/// <param name="a">long a.</param>
/// <param name="b">long b.</param>
public v128(long a, long b)
{
this = default(v128);
SLong0 = a;
SLong1 = b;
}
/// <summary>
/// Splat a single ulong across the v128
/// </summary>
/// <param name="f">Splatted ulong.</param>
public v128(ulong f)
{
this = default(v128);
ULong0 = ULong1 = f;
}
/// <summary>
/// Initialize the v128 with 2 ulongs
/// </summary>
/// <param name="a">ulong a.</param>
/// <param name="b">ulong b.</param>
public v128(ulong a, ulong b)
{
this = default(v128);
ULong0 = a;
ULong1 = b;
}
/// <summary>
/// Initialize the v128 with 2 v64's
/// </summary>
/// <param name="lo">Low half of v64.</param>
/// <param name="hi">High half of v64.</param>
public v128(v64 lo, v64 hi)
{
this = default(v128);
Lo64 = lo;
Hi64 = hi;
}
}
#if BURST_INTERNAL || UNITY_BURST_EXPERIMENTAL_NEON_INTRINSICS
/// <summary>
/// Represents a 256-bit SIMD value (Arm only)
/// (a combination of 2 128-bit values, equivalent to Arm Neon *x2 types)
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public struct v128x2
{
/// <summary>
/// Get the first 128 bits of the vector
/// </summary>
[FieldOffset(0)] public v128 v128_0;
/// <summary>
/// Get the second 128 bits of the vector
/// </summary>
[FieldOffset(16)] public v128 v128_1;
/// <summary>
/// Initialize the v128x2 with 2 v128's
/// </summary>
/// <param name="v0">First v128.</param>
/// <param name="v1">Second v128.</param>
public v128x2(v128 v0, v128 v1)
{
this = default(v128x2);
v128_0 = v0;
v128_1 = v1;
}
}
/// <summary>
/// Represents a 384-bit SIMD value (Arm only)
/// (a combination of 3 128-bit values, equivalent to Arm Neon *x3 types)
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public struct v128x3
{
/// <summary>
/// Get the first 128 bits of the vector
/// </summary>
[FieldOffset(0)] public v128 v128_0;
/// <summary>
/// Get the second 128 bits of the vector
/// </summary>
[FieldOffset(16)] public v128 v128_1;
/// <summary>
/// Get the third 128 bits of the vector
/// </summary>
[FieldOffset(32)] public v128 v128_2;
/// <summary>
/// Initialize the v128x3 with 3 v128's
/// </summary>
/// <param name="v0">First v128.</param>
/// <param name="v1">Second v128.</param>
/// <param name="v2">Third v128.</param>
public v128x3(v128 v0, v128 v1, v128 v2)
{
this = default(v128x3);
v128_0 = v0;
v128_1 = v1;
v128_2 = v2;
}
}
/// <summary>
/// Represents a 512-bit SIMD value (Arm only)
/// (a combination of 4 128-bit values, equivalent to Arm Neon *x4 types)
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public struct v128x4
{
/// <summary>
/// Get the first 128 bits of the vector
/// </summary>
[FieldOffset(0)] public v128 v128_0;
/// <summary>
/// Get the second 128 bits of the vector
/// </summary>
[FieldOffset(16)] public v128 v128_1;
/// <summary>
/// Get the third 128 bits of the vector
/// </summary>
[FieldOffset(32)] public v128 v128_2;
/// <summary>
/// Get the fourth 128 bits of the vector
/// </summary>
[FieldOffset(48)] public v128 v128_3;
/// <summary>
/// Initialize the v128x4 with 4 v128's
/// </summary>
/// <param name="v0">First v128.</param>
/// <param name="v1">Second v128.</param>
/// <param name="v2">Third v128.</param>
/// <param name="v3">Fourth v128.</param>
public v128x4(v128 v0, v128 v1, v128 v2, v128 v3)
{
this = default(v128x4);
v128_0 = v0;
v128_1 = v1;
v128_2 = v2;
v128_3 = v3;
}
}
#endif // BURST_INTERNAL || UNITY_BURST_EXPERIMENTAL_NEON_INTRINSICS
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: de21742a4b9139f3a58692cb231ecd51
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b7010e2961793c8ab9d5fec3d5c886d0
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,530 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Unity.Burst.Intrinsics
{
/// <summary>
/// Represents a 64-bit SIMD value (Arm only)
/// </summary>
[StructLayout(LayoutKind.Explicit)]
[DebuggerTypeProxy(typeof(V64DebugView))]
public struct v64
{
/// <summary>
/// Get the 0th Byte of the vector
/// </summary>
[FieldOffset(0)] public byte Byte0;
/// <summary>
/// Get the 1st Byte of the vector
/// </summary>
[FieldOffset(1)] public byte Byte1;
/// <summary>
/// Get the 2nd Byte of the vector
/// </summary>
[FieldOffset(2)] public byte Byte2;
/// <summary>
/// Get the 3rd Byte of the vector
/// </summary>
[FieldOffset(3)] public byte Byte3;
/// <summary>
/// Get the 4th Byte of the vector
/// </summary>
[FieldOffset(4)] public byte Byte4;
/// <summary>
/// Get the 5th Byte of the vector
/// </summary>
[FieldOffset(5)] public byte Byte5;
/// <summary>
/// Get the 6th Byte of the vector
/// </summary>
[FieldOffset(6)] public byte Byte6;
/// <summary>
/// Get the 7th Byte of the vector
/// </summary>
[FieldOffset(7)] public byte Byte7;
/// <summary>
/// Get the 0th SByte of the vector
/// </summary>
[FieldOffset(0)] public sbyte SByte0;
/// <summary>
/// Get the 1st SByte of the vector
/// </summary>
[FieldOffset(1)] public sbyte SByte1;
/// <summary>
/// Get the 2nd SByte of the vector
/// </summary>
[FieldOffset(2)] public sbyte SByte2;
/// <summary>
/// Get the 3rd SByte of the vector
/// </summary>
[FieldOffset(3)] public sbyte SByte3;
/// <summary>
/// Get the 4th SByte of the vector
/// </summary>
[FieldOffset(4)] public sbyte SByte4;
/// <summary>
/// Get the 5th SByte of the vector
/// </summary>
[FieldOffset(5)] public sbyte SByte5;
/// <summary>
/// Get the 6th SByte of the vector
/// </summary>
[FieldOffset(6)] public sbyte SByte6;
/// <summary>
/// Get the 7th SByte of the vector
/// </summary>
[FieldOffset(7)] public sbyte SByte7;
/// <summary>
/// Get the 0th UShort of the vector
/// </summary>
[FieldOffset(0)] public ushort UShort0;
/// <summary>
/// Get the 1st UShort of the vector
/// </summary>
[FieldOffset(2)] public ushort UShort1;
/// <summary>
/// Get the 2nd UShort of the vector
/// </summary>
[FieldOffset(4)] public ushort UShort2;
/// <summary>
/// Get the 3rd UShort of the vector
/// </summary>
[FieldOffset(6)] public ushort UShort3;
/// <summary>
/// Get the 0th SShort of the vector
/// </summary>
[FieldOffset(0)] public short SShort0;
/// <summary>
/// Get the 1st SShort of the vector
/// </summary>
[FieldOffset(2)] public short SShort1;
/// <summary>
/// Get the 2nd SShort of the vector
/// </summary>
[FieldOffset(4)] public short SShort2;
/// <summary>
/// Get the 3rd SShort of the vector
/// </summary>
[FieldOffset(6)] public short SShort3;
#if BURST_INTERNAL || UNITY_BURST_EXPERIMENTAL_NEON_INTRINSICS
/// <summary>
/// Get the 0th f16 of the vector
/// </summary>
[FieldOffset(0)] public f16 Half0;
/// <summary>
/// Get the 1st f16 of the vector
/// </summary>
[FieldOffset(2)] public f16 Half1;
/// <summary>
/// Get the 2nd f16 of the vector
/// </summary>
[FieldOffset(4)] public f16 Half2;
/// <summary>
/// Get the 3rd f16 of the vector
/// </summary>
[FieldOffset(6)] public f16 Half3;
#endif // BURST_INTERNAL || UNITY_BURST_EXPERIMENTAL_NEON_INTRINSICS
/// <summary>
/// Get the 0th UInt of the vector
/// </summary>
[FieldOffset(0)] public uint UInt0;
/// <summary>
/// Get the 1st UInt of the vector
/// </summary>
[FieldOffset(4)] public uint UInt1;
/// <summary>
/// Get the 0th SInt of the vector
/// </summary>
[FieldOffset(0)] public int SInt0;
/// <summary>
/// Get the 1st SInt of the vector
/// </summary>
[FieldOffset(4)] public int SInt1;
/// <summary>
/// Get the 0th ULong of the vector
/// </summary>
[FieldOffset(0)] public ulong ULong0;
/// <summary>
/// Get the 0th SLong of the vector
/// </summary>
[FieldOffset(0)] public long SLong0;
/// <summary>
/// Get the 0th Float of the vector
/// </summary>
[FieldOffset(0)] public float Float0;
/// <summary>
/// Get the 1st Float of the vector
/// </summary>
[FieldOffset(4)] public float Float1;
/// <summary>
/// Get the 0th Double of the vector
/// </summary>
[FieldOffset(0)] public double Double0;
/// <summary>
/// Splat a single byte across the v64
/// </summary>
/// <param name="b">Splatted byte</param>
public v64(byte b)
{
this = default(v64);
Byte0 = Byte1 = Byte2 = Byte3 = Byte4 = Byte5 = Byte6 = Byte7 = b;
}
/// <summary>
/// Initialize the v64 with 8 bytes
/// </summary>
/// <param name="a">byte a</param>
/// <param name="b">byte b</param>
/// <param name="c">byte c</param>
/// <param name="d">byte d</param>
/// <param name="e">byte e</param>
/// <param name="f">byte f</param>
/// <param name="g">byte g</param>
/// <param name="h">byte h</param>
public v64(
byte a, byte b, byte c, byte d,
byte e, byte f, byte g, byte h)
{
this = default(v64);
Byte0 = a;
Byte1 = b;
Byte2 = c;
Byte3 = d;
Byte4 = e;
Byte5 = f;
Byte6 = g;
Byte7 = h;
}
/// <summary>
/// Splat a single sbyte across the v64
/// </summary>
/// <param name="b">Splatted sbyte</param>
public v64(sbyte b)
{
this = default(v64);
SByte0 = SByte1 = SByte2 = SByte3 = SByte4 = SByte5 = SByte6 = SByte7 = b;
}
/// <summary>
/// Initialize the v64 with 8 sbytes
/// </summary>
/// <param name="a">sbyte a</param>
/// <param name="b">sbyte b</param>
/// <param name="c">sbyte c</param>
/// <param name="d">sbyte d</param>
/// <param name="e">sbyte e</param>
/// <param name="f">sbyte f</param>
/// <param name="g">sbyte g</param>
/// <param name="h">sbyte h</param>
public v64(
sbyte a, sbyte b, sbyte c, sbyte d,
sbyte e, sbyte f, sbyte g, sbyte h)
{
this = default(v64);
SByte0 = a;
SByte1 = b;
SByte2 = c;
SByte3 = d;
SByte4 = e;
SByte5 = f;
SByte6 = g;
SByte7 = h;
}
/// <summary>
/// Splat a single short across the v64
/// </summary>
/// <param name="v">Splatted short</param>
public v64(short v)
{
this = default(v64);
SShort0 = SShort1 = SShort2 = SShort3 = v;
}
/// <summary>
/// Initialize the v64 with 4 shorts
/// </summary>
/// <param name="a">short a</param>
/// <param name="b">short b</param>
/// <param name="c">short c</param>
/// <param name="d">short d</param>
public v64(short a, short b, short c, short d)
{
this = default(v64);
SShort0 = a;
SShort1 = b;
SShort2 = c;
SShort3 = d;
}
/// <summary>
/// Splat a single ushort across the v64
/// </summary>
/// <param name="v">Splatted ushort</param>
public v64(ushort v)
{
this = default(v64);
UShort0 = UShort1 = UShort2 = UShort3 = v;
}
/// <summary>
/// Initialize the v64 with 4 ushorts
/// </summary>
/// <param name="a">ushort a</param>
/// <param name="b">ushort b</param>
/// <param name="c">ushort c</param>
/// <param name="d">ushort d</param>
public v64(ushort a, ushort b, ushort c, ushort d)
{
this = default(v64);
UShort0 = a;
UShort1 = b;
UShort2 = c;
UShort3 = d;
}
#if BURST_INTERNAL || UNITY_BURST_EXPERIMENTAL_NEON_INTRINSICS
/// <summary>
/// Splat a single f16 across the v64
/// </summary>
/// <param name="v">Splatted f16</param>
public v64(f16 v)
{
this = default(v64);
Half0 = Half1 = Half2 = Half3 = v;
}
/// <summary>
/// Initialize the v64 with 4 half's
/// </summary>
/// <param name="a">f16 a</param>
/// <param name="b">f16 b</param>
/// <param name="c">f16 c</param>
/// <param name="d">f16 d</param>
public v64(f16 a, f16 b, f16 c, f16 d)
{
this = default(v64);
Half0 = a;
Half1 = b;
Half2 = c;
Half3 = d;
}
#endif // BURST_INTERNAL || UNITY_BURST_EXPERIMENTAL_NEON_INTRINSICS
/// <summary>
/// Splat a single int across the v64
/// </summary>
/// <param name="v">Splatted int</param>
public v64(int v)
{
this = default(v64);
SInt0 = SInt1 = v;
}
/// <summary>
/// Initialize the v64 with 2 ints
/// </summary>
/// <param name="a">int a</param>
/// <param name="b">int b</param>
public v64(int a, int b)
{
this = default(v64);
SInt0 = a;
SInt1 = b;
}
/// <summary>
/// Splat a single uint across the v64
/// </summary>
/// <param name="v">Splatted uint</param>
public v64(uint v)
{
this = default(v64);
UInt0 = UInt1 = v;
}
/// <summary>
/// Initialize the v64 with 2 uints
/// </summary>
/// <param name="a">uint a</param>
/// <param name="b">uint b</param>
public v64(uint a, uint b)
{
this = default(v64);
UInt0 = a;
UInt1 = b;
}
/// <summary>
/// Splat a single float across the v64
/// </summary>
/// <param name="f">Splatted float</param>
public v64(float f)
{
this = default(v64);
Float0 = Float1 = f;
}
/// <summary>
/// Initialize the v64 with 2 floats
/// </summary>
/// <param name="a">float a</param>
/// <param name="b">float b</param>
public v64(float a, float b)
{
this = default(v64);
Float0 = a;
Float1 = b;
}
/// <summary>
/// Initialize the v64 with a double
/// </summary>
/// <param name="a">Splatted double</param>
public v64(double a)
{
this = default(v64);
Double0 = a;
}
/// <summary>
/// Initialize the v64 with a long
/// </summary>
/// <param name="a">long a</param>
public v64(long a)
{
this = default(v64);
SLong0 = a;
}
/// <summary>
/// Initialize the v64 with a ulong
/// </summary>
/// <param name="a">ulong a</param>
public v64(ulong a)
{
this = default(v64);
ULong0 = a;
}
}
#if BURST_INTERNAL || UNITY_BURST_EXPERIMENTAL_NEON_INTRINSICS
/// <summary>
/// Represents a 128-bit SIMD value (Arm only)
/// (a combination of 2 64-bit values, equivalent to Arm Neon *x2 types)
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public struct v64x2
{
/// <summary>
/// Get the first 64 bits of the vector
/// </summary>
[FieldOffset(0)] public v64 v64_0;
/// <summary>
/// Get the second 64 bits of the vector
/// </summary>
[FieldOffset(8)] public v64 v64_1;
/// <summary>
/// Initialize the v64x2 with 2 v64's
/// </summary>
/// <param name="v0">First v64.</param>
/// <param name="v1">Second v64.</param>
public v64x2(v64 v0, v64 v1)
{
this = default(v64x2);
v64_0 = v0;
v64_1 = v1;
}
}
/// <summary>
/// Represents a 192-bit SIMD value (Arm only)
/// (a combination of 3 64-bit values, equivalent to Arm Neon *x3 types)
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public struct v64x3
{
/// <summary>
/// Get the first 64 bits of the vector
/// </summary>
[FieldOffset(0)] public v64 v64_0;
/// <summary>
/// Get the second 64 bits of the vector
/// </summary>
[FieldOffset(8)] public v64 v64_1;
/// <summary>
/// Get the third 64 bits of the vector
/// </summary>
[FieldOffset(16)] public v64 v64_2;
/// <summary>
/// Initialize the v64x3 with 3 v64's
/// </summary>
/// <param name="v0">First v64.</param>
/// <param name="v1">Second v64.</param>
/// <param name="v2">Third v64.</param>
public v64x3(v64 v0, v64 v1, v64 v2)
{
this = default(v64x3);
v64_0 = v0;
v64_1 = v1;
v64_2 = v2;
}
}
/// <summary>
/// Represents a 256-bit SIMD value (Arm only)
/// (a combination of 4 64-bit values, equivalent to Arm Neon *x4 types)
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public struct v64x4
{
/// <summary>
/// Get the first 64 bits of the vector
/// </summary>
[FieldOffset(0)] public v64 v64_0;
/// <summary>
/// Get the second 64 bits of the vector
/// </summary>
[FieldOffset(8)] public v64 v64_1;
/// <summary>
/// Get the third 64 bits of the vector
/// </summary>
[FieldOffset(16)] public v64 v64_2;
/// <summary>
/// Get the fourth 64 bits of the vector
/// </summary>
[FieldOffset(24)] public v64 v64_3;
/// <summary>
/// Initialize the v64x4 with 4 v64's
/// </summary>
/// <param name="v0">First v64.</param>
/// <param name="v1">Second v64.</param>
/// <param name="v2">Third v64.</param>
/// <param name="v3">Fourth v64.</param>
public v64x4(v64 v0, v64 v1, v64 v2, v64 v3)
{
this = default(v64x4);
v64_0 = v0;
v64_1 = v1;
v64_2 = v2;
v64_3 = v3;
}
}
#endif // BURST_INTERNAL || UNITY_BURST_EXPERIMENTAL_NEON_INTRINSICS
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 96f6238860a6336296ab17b81a3cc3a2
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3413d06997203e50844bbf4eca32fce8
folderAsset: yes

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fb77e3d4fbde3090a07ebac108e13ed8
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bbe744fdbbc734d3bb0a78042bd4b56a
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,276 @@
using System.Diagnostics;
namespace Unity.Burst.Intrinsics
{
public unsafe static partial class X86
{
/// <summary>
/// bmi1 intrinsics
/// </summary>
public static class Bmi1
{
/// <summary>
/// Evaluates to true at compile time if bmi1 intrinsics are supported.
///
/// Burst ties bmi1 support to AVX2 support to simplify feature sets to support.
/// </summary>
public static bool IsBmi1Supported { get { return Avx2.IsAvx2Supported; } }
/// <summary>
/// Compute the bitwise NOT of 32-bit integer a and then AND with b, and store the results in dst.
/// </summary>
/// <remarks>
/// **** andn r32, r32, r32
/// </remarks>
/// <param name="a">32-bit integer</param>
/// <param name="b">32-bit integer</param>
/// <returns>32-bit integer</returns>
[DebuggerStepThrough]
public static uint andn_u32(uint a, uint b)
{
return ~a & b;
}
/// <summary>
/// Compute the bitwise NOT of 64-bit integer a and then AND with b, and store the results in dst.
/// </summary>
/// <remarks>
/// **** andn r64, r64, r64
/// </remarks>
/// <param name="a">64-bit integer</param>
/// <param name="b">64-bit integer</param>
/// <returns>64-bit integer</returns>
[DebuggerStepThrough]
public static ulong andn_u64(ulong a, ulong b)
{
return ~a & b;
}
/// <summary>
/// Extract contiguous bits from unsigned 32-bit integer a, and store the result in dst. Extract the number of bits specified by len, starting at the bit specified by start.
/// </summary>
/// <remarks>
/// **** bextr r32, r32, r32
/// </remarks>
/// <param name="a">32-bit integer</param>
/// <param name="start">Starting bit</param>
/// <param name="len">Number of bits</param>
/// <returns>32-bit integer</returns>
[DebuggerStepThrough]
public static uint bextr_u32(uint a, uint start, uint len)
{
start &= 0xff;
if (start >= (sizeof(uint) * 8))
{
return 0;
}
var aShifted = a >> (int)start;
len &= 0xff;
if (len >= (sizeof(uint) * 8))
{
return aShifted;
}
return aShifted & ((1u << (int)len) - 1u);
}
/// <summary>
/// Extract contiguous bits from unsigned 64-bit integer a, and store the result in dst. Extract the number of bits specified by len, starting at the bit specified by start.
/// </summary>
/// <remarks>
/// **** bextr r64, r64, r64
/// </remarks>
/// <param name="a">64-bit integer</param>
/// <param name="start">Starting bit</param>
/// <param name="len">Number of bits</param>
/// <returns>64-bit integer</returns>
[DebuggerStepThrough]
public static ulong bextr_u64(ulong a, uint start, uint len)
{
start &= 0xff;
if (start >= (sizeof(ulong) * 8))
{
return 0;
}
var aShifted = a >> (int)start;
len &= 0xff;
if (len >= (sizeof(ulong) * 8))
{
return aShifted;
}
return aShifted & (((1ul) << (int)len) - 1u);
}
/// <summary>
/// Extract contiguous bits from unsigned 32-bit integer a, and store the result in dst. Extract the number of bits specified by bits 15:8 of control, starting at the bit specified by bits 0:7 of control..
/// </summary>
/// <remarks>
/// **** bextr r32, r32, r32
/// </remarks>
/// <param name="a">32-bit integer</param>
/// <param name="control">Control</param>
/// <returns>32-bit integer</returns>
[DebuggerStepThrough]
public static uint bextr2_u32(uint a, uint control)
{
uint start = control & byte.MaxValue;
uint len = (control >> 8) & byte.MaxValue;
return bextr_u32(a, start, len);
}
/// <summary>
/// Extract contiguous bits from unsigned 64-bit integer a, and store the result in dst. Extract the number of bits specified by bits 15:8 of control, starting at the bit specified by bits 0:7 of control..
/// </summary>
/// <remarks>
/// **** bextr r64, r64, r64
/// </remarks>
/// <param name="a">32-bit integer</param>
/// <param name="control">Control</param>
/// <returns>64-bit integer</returns>
[DebuggerStepThrough]
public static ulong bextr2_u64(ulong a, ulong control)
{
uint start = (uint)(control & byte.MaxValue);
uint len = (uint)((control >> 8) & byte.MaxValue);
return bextr_u64(a, start, len);
}
/// <summary>
/// Extract the lowest set bit from unsigned 32-bit integer a and set the corresponding bit in dst. All other bits in dst are zeroed, and all bits are zeroed if no bits are set in a.
/// </summary>
/// <remarks>
/// **** blsi r32, r32
/// </remarks>
/// <param name="a">32-bit integer</param>
/// <returns>32-bit integer</returns>
[DebuggerStepThrough]
public static uint blsi_u32(uint a)
{
return (uint)(-(int)a) & a;
}
/// <summary>
/// Extract the lowest set bit from unsigned 64-bit integer a and set the corresponding bit in dst. All other bits in dst are zeroed, and all bits are zeroed if no bits are set in a.
/// </summary>
/// <remarks>
/// **** blsi r64, r64
/// </remarks>
/// <param name="a">64-bit integer</param>
/// <returns>64-bit integer</returns>
[DebuggerStepThrough]
public static ulong blsi_u64(ulong a)
{
return (ulong)(-(long)a) & a;
}
/// <summary>
/// Set all the lower bits of dst up to and including the lowest set bit in unsigned 32-bit integer a.
/// </summary>
/// <remarks>
/// **** blsmsk r32, r32
/// </remarks>
/// <param name="a">32-bit integer</param>
/// <returns>32-bit integer</returns>
[DebuggerStepThrough]
public static uint blsmsk_u32(uint a)
{
return (a - 1) ^ a;
}
/// <summary>
/// Set all the lower bits of dst up to and including the lowest set bit in unsigned 64-bit integer a.
/// </summary>
/// <remarks>
/// **** blsmsk r64, r64
/// </remarks>
/// <param name="a">64-bit integer</param>
/// <returns>64-bit integer</returns>
[DebuggerStepThrough]
public static ulong blsmsk_u64(ulong a)
{
return (a - 1) ^ a;
}
/// <summary>
/// Copy all bits from unsigned 32-bit integer a to dst, and reset (set to 0) the bit in dst that corresponds to the lowest set bit in a.
/// </summary>
/// <remarks>
/// **** blsr r32, r32
/// </remarks>
/// <param name="a">32-bit integer</param>
/// <returns>32-bit integer</returns>
[DebuggerStepThrough]
public static uint blsr_u32(uint a)
{
return (a - 1) & a;
}
/// <summary>
/// Copy all bits from unsigned 64-bit integer a to dst, and reset (set to 0) the bit in dst that corresponds to the lowest set bit in a.
/// </summary>
/// <remarks>
/// **** blsr r64, r64
/// </remarks>
/// <param name="a">64-bit integer</param>
/// <returns>64-bit integer</returns>
[DebuggerStepThrough]
public static ulong blsr_u64(ulong a)
{
return (a - 1) & a;
}
/// <summary>
/// Count the number of trailing zero bits in unsigned 32-bit integer a, and return that count in dst.
/// </summary>
/// <remarks>
/// **** tzcnt r32, r32
/// </remarks>
/// <param name="a">32-bit integer</param>
/// <returns>32-bit integer</returns>
[DebuggerStepThrough]
public static uint tzcnt_u32(uint a)
{
uint c = 32;
a &= (uint)-(int)(a);
if (a != 0) c--;
if ((a & 0x0000FFFF) != 0) c -= 16;
if ((a & 0x00FF00FF) != 0) c -= 8;
if ((a & 0x0F0F0F0F) != 0) c -= 4;
if ((a & 0x33333333) != 0) c -= 2;
if ((a & 0x55555555) != 0) c -= 1;
return c;
}
/// <summary>
/// Count the number of trailing zero bits in unsigned 64-bit integer a, and return that count in dst.
/// </summary>
/// <remarks>
/// **** tzcnt r64, r64
/// </remarks>
/// <param name="a">64-bit integer</param>
/// <returns>64-bit integer</returns>
[DebuggerStepThrough]
public static ulong tzcnt_u64(ulong a)
{
ulong c = 64;
a &= (ulong)-(long)(a);
if (a != 0) c--;
if ((a & 0x00000000FFFFFFFF) != 0) c -= 32;
if ((a & 0x0000FFFF0000FFFF) != 0) c -= 16;
if ((a & 0x00FF00FF00FF00FF) != 0) c -= 8;
if ((a & 0x0F0F0F0F0F0F0F0F) != 0) c -= 4;
if ((a & 0x3333333333333333) != 0) c -= 2;
if ((a & 0x5555555555555555) != 0) c -= 1;
return c;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bae2d17db94135ea84f8110705ba44a0
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,212 @@
using System.Diagnostics;
namespace Unity.Burst.Intrinsics
{
public unsafe static partial class X86
{
/// <summary>
/// bmi2 intrinsics
/// </summary>
public static class Bmi2
{
/// <summary>
/// Evaluates to true at compile time if bmi2 intrinsics are supported.
///
/// Burst ties bmi2 support to AVX2 support to simplify feature sets to support.
/// </summary>
public static bool IsBmi2Supported { get { return Avx2.IsAvx2Supported; } }
/// <summary>
/// Copy all bits from unsigned 32-bit integer a to dst, and reset (set to 0) the high bits in dst starting at index.
/// </summary>
/// <remarks>
/// **** bzhi r32, r32, r32
/// </remarks>
/// <param name="a">32-bit integer</param>
/// <param name="index">Starting point</param>
/// <returns>32-bit integer</returns>
[DebuggerStepThrough]
public static uint bzhi_u32(uint a, uint index)
{
index &= 0xff;
if (index >= (sizeof(uint) * 8))
{
return a;
}
return a & ((1u << (int)index) - 1u);
}
/// <summary>
/// Copy all bits from unsigned 64-bit integer a to dst, and reset (set to 0) the high bits in dst starting at index.
/// </summary>
/// <remarks>
/// **** bzhi r64, r64, r64
/// </remarks>
/// <param name="a">64-bit integer</param>
/// <param name="index">Starting point</param>
/// <returns>64-bit integer</returns>
[DebuggerStepThrough]
public static ulong bzhi_u64(ulong a, ulong index)
{
index &= 0xff;
if (index >= (sizeof(ulong) * 8))
{
return a;
}
return a & ((1ul << (int)index) - 1ul);
}
/// <summary>
/// Multiply unsigned 32-bit integers a and b, store the low 32-bits of the result in dst, and store the high 32-bits in hi. This does not read or write arithmetic flags.
/// </summary>
/// <remarks>
/// **** mulx r32, r32, m32
/// </remarks>
/// <param name="a">32-bit integer</param>
/// <param name="b">32-bit integer</param>
/// <param name="hi">Stores the high 32-bits</param>
/// <returns>32-bit integer</returns>
[DebuggerStepThrough]
public static uint mulx_u32(uint a, uint b, out uint hi)
{
ulong aBig = a;
ulong bBig = b;
ulong result = aBig * bBig;
hi = (uint)(result >> 32);
return (uint)(result & 0xffffffff);
}
/// <summary>
/// Multiply unsigned 64-bit integers a and b, store the low 64-bits of the result in dst, and store the high 64-bits in hi. This does not read or write arithmetic flags.
/// </summary>
/// <remarks>
/// **** mulx r64, r64, m64
/// </remarks>
/// <param name="a">64-bit integer</param>
/// <param name="b">64-bit integer</param>
/// <param name="hi">Stores the high 64-bits</param>
/// <returns>64-bit integer</returns>
[DebuggerStepThrough]
public static ulong mulx_u64(ulong a, ulong b, out ulong hi)
{
return Common.umul128(a, b, out hi);
}
/// <summary>
/// Deposit contiguous low bits from unsigned 32-bit integer a to dst at the corresponding bit locations specified by mask; all other bits in dst are set to zero.
/// </summary>
/// <remarks>
/// **** pdep r32, r32, r32
/// </remarks>
/// <param name="a">32-bit integer</param>
/// <param name="mask">Mask</param>
/// <returns>32-bit integer</returns>
[DebuggerStepThrough]
public static uint pdep_u32(uint a, uint mask)
{
uint result = 0;
int k = 0;
for (int i = 0; i < 32; i++)
{
if ((mask & (1u << i)) != 0)
{
result |= ((a >> k) & 1u) << i;
k++;
}
}
return result;
}
/// <summary>
/// Deposit contiguous low bits from unsigned 64-bit integer a to dst at the corresponding bit locations specified by mask; all other bits in dst are set to zero.
/// </summary>
/// <remarks>
/// **** pdep r64, r64, r64
/// </remarks>
/// <param name="a">64-bit integer</param>
/// <param name="mask">Mask</param>
/// <returns>64-bit integer</returns>
[DebuggerStepThrough]
public static ulong pdep_u64(ulong a, ulong mask)
{
ulong result = 0;
int k = 0;
for (int i = 0; i < 64; i++)
{
if ((mask & (1ul << i)) != 0)
{
result |= ((a >> k) & 1ul) << i;
k++;
}
}
return result;
}
/// <summary>
/// Extract bits from unsigned 32-bit integer a at the corresponding bit locations specified by mask to contiguous low bits in dst; the remaining upper bits in dst are set to zero.
/// </summary>
/// <remarks>
/// **** pext r32, r32, r32
/// </remarks>
/// <param name="a">32-bit integer</param>
/// <param name="mask">Mask</param>
/// <returns>32-bit integer</returns>
[DebuggerStepThrough]
public static uint pext_u32(uint a, uint mask)
{
uint result = 0;
int k = 0;
for (int i = 0; i < 32; i++)
{
if ((mask & (1u << i)) != 0)
{
result |= ((a >> i) & 1u) << k;
k++;
}
}
return result;
}
/// <summary>
/// Extract bits from unsigned 64-bit integer a at the corresponding bit locations specified by mask to contiguous low bits in dst; the remaining upper bits in dst are set to zero.
/// </summary>
/// <remarks>
/// **** pext r64, r64, r64
/// </remarks>
/// <param name="a">64-bit integer</param>
/// <param name="mask">Mask</param>
/// <returns>64-bit integer</returns>
[DebuggerStepThrough]
public static ulong pext_u64(ulong a, ulong mask)
{
ulong result = 0;
int k = 0;
for (int i = 0; i < 64; i++)
{
if ((mask & (1ul << i)) != 0)
{
result |= ((a >> i) & 1ul) << k;
k++;
}
}
return result;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: aa392f69e52b37a486ca7cfa6125fd60
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,66 @@
using System;
namespace Unity.Burst.Intrinsics
{
/// <summary>
/// Static methods and properties for X86 instruction intrinsics.
/// </summary>
public unsafe static partial class X86
{
private static v128 GenericCSharpLoad(void* ptr)
{
return *(v128*)ptr;
}
private static void GenericCSharpStore(void* ptr, v128 val)
{
*(v128*)ptr = val;
}
private static sbyte Saturate_To_Int8(int val)
{
if (val > sbyte.MaxValue)
return sbyte.MaxValue;
else if (val < sbyte.MinValue)
return sbyte.MinValue;
return (sbyte)val;
}
private static byte Saturate_To_UnsignedInt8(int val)
{
if (val > byte.MaxValue)
return byte.MaxValue;
else if (val < byte.MinValue)
return byte.MinValue;
return (byte)val;
}
private static short Saturate_To_Int16(int val)
{
if (val > short.MaxValue)
return short.MaxValue;
else if (val < short.MinValue)
return short.MinValue;
return (short)val;
}
private static ushort Saturate_To_UnsignedInt16(int val)
{
if (val > ushort.MaxValue)
return ushort.MaxValue;
else if (val < ushort.MinValue)
return ushort.MinValue;
return (ushort)val;
}
private static bool IsNaN(uint v)
{
return (v & 0x7fffffffu) > 0x7f800000;
}
private static bool IsNaN(ulong v)
{
return (v & 0x7ffffffffffffffful) > 0x7ff0000000000000ul;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 000378914c63384c8062cbad18605802
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,269 @@
using System;
using Unity.Burst;
#if !BURST_INTERNAL
using AOT;
using UnityEngine;
#endif
using System.Runtime.InteropServices;
namespace Unity.Burst.Intrinsics
{
#if !BURST_INTERNAL
[BurstCompile]
#endif
public unsafe static partial class X86
{
/// <summary>
/// The 32-bit MXCSR register contains control and status information for SSE and AVX SIMD floating-point operations.
/// </summary>
[Flags]
public enum MXCSRBits
{
/// <summary>
/// Bit 15 (FTZ) of the MXCSR register enables the flush-to-zero mode, which controls the masked response to a SIMD floating-point underflow condition.
/// </summary>
/// <remarks>
/// When the underflow exception is masked and the flush-to-zero mode is enabled, the processor performs the following operations when it detects a floating-point underflow condition.
/// - Returns a zero result with the sign of the true result
/// - Sets the precision and underflow exception flags.
///
/// If the underflow exception is not masked, the flush-to-zero bit is ignored.
///
/// The flush-to-zero mode is not compatible with IEEE Standard 754. The IEEE-mandated masked response to under-flow is to deliver the denormalized result.
/// The flush-to-zero mode is provided primarily for performance reasons. At the cost of a slight precision loss, faster execution can be achieved for applications where underflows
/// are common and rounding the underflow result to zero can be tolerated. The flush-to-zero bit is cleared upon a power-up or reset of the processor, disabling the flush-to-zero mode.
/// </remarks>
FlushToZero = 1 << 15,
/// <summary>
/// Mask for rounding control bits.
/// </summary>
/// <remarks>
/// The rounding modes have no effect on comparison operations, operations that produce exact results, or operations that produce NaN results.
/// </remarks>
RoundingControlMask = (1 << 14) | (1 << 13),
/// <summary>
/// Rounded result is the closest to the infinitely precise result. If two values are equally close, the result is the even value (that is, the one with the least-significant bit of zero). Default.
/// </summary>
RoundToNearest = 0,
/// <summary>
/// Rounded result is closest to but no greater than the infinitely precise result.
/// </summary>
RoundDown = (1 << 13),
/// <summary>
/// Rounded result is closest to but no less than the infinitely precise result.
/// </summary>
RoundUp = (1 << 14),
/// <summary>
/// Rounded result is closest to but no greater in absolute value than the infinitely precise result.
/// </summary>
RoundTowardZero = (1 << 13) | (1 << 14),
/// <summary>Bits 7 through 12 provide individual mask bits for the SIMD floating-point exceptions. An exception type is masked if the corresponding mask bit is set, and it is unmasked if the bit is clear. These mask bits are set upon a power-up or reset. This causes all SIMD floating-point exceptions to be initially masked.</summary>
PrecisionMask = 1 << 12,
/// <summary>Bits 7 through 12 provide individual mask bits for the SIMD floating-point exceptions. An exception type is masked if the corresponding mask bit is set, and it is unmasked if the bit is clear. These mask bits are set upon a power-up or reset. This causes all SIMD floating-point exceptions to be initially masked.</summary>
UnderflowMask = 1 << 11,
/// <summary>Bits 7 through 12 provide individual mask bits for the SIMD floating-point exceptions. An exception type is masked if the corresponding mask bit is set, and it is unmasked if the bit is clear. These mask bits are set upon a power-up or reset. This causes all SIMD floating-point exceptions to be initially masked.</summary>
OverflowMask = 1 << 10,
/// <summary>Bits 7 through 12 provide individual mask bits for the SIMD floating-point exceptions. An exception type is masked if the corresponding mask bit is set, and it is unmasked if the bit is clear. These mask bits are set upon a power-up or reset. This causes all SIMD floating-point exceptions to be initially masked.</summary>
DivideByZeroMask = 1 << 9,
/// <summary>Bits 7 through 12 provide individual mask bits for the SIMD floating-point exceptions. An exception type is masked if the corresponding mask bit is set, and it is unmasked if the bit is clear. These mask bits are set upon a power-up or reset. This causes all SIMD floating-point exceptions to be initially masked.</summary>
DenormalOperationMask = 1 << 8,
/// <summary>Bits 7 through 12 provide individual mask bits for the SIMD floating-point exceptions. An exception type is masked if the corresponding mask bit is set, and it is unmasked if the bit is clear. These mask bits are set upon a power-up or reset. This causes all SIMD floating-point exceptions to be initially masked.</summary>
InvalidOperationMask = 1 << 7,
/// <summary>
/// Combine all bits for exception masking into one mask for convenience.
/// </summary>
ExceptionMask = PrecisionMask | UnderflowMask | OverflowMask | DivideByZeroMask | DenormalOperationMask | InvalidOperationMask,
/// <summary>
/// Bit 6 (DAZ) of the MXCSR register enables the denormals-are-zeros mode, which controls the processors response to a SIMD floating-point denormal operand condition.
/// </summary>
/// <remarks>
/// When the denormals-are-zeros flag is set, the processor converts all denormal source operands to a zero with the sign of the original operand before performing any computations on them.
/// The processor does not set the denormal-operand exception flag (DE), regardless of the setting of the denormal-operand exception mask bit (DM); and it does not generate a denormal-operand
/// exception if the exception is unmasked.The denormals-are-zeros mode is not compatible with IEEE Standard 754.
///
/// The denormals-are-zeros mode is provided to improve processor performance for applications such as streaming media processing, where rounding a denormal operand to zero does not
/// appreciably affect the quality of the processed data. The denormals-are-zeros flag is cleared upon a power-up or reset of the processor, disabling the denormals-are-zeros mode.
///
/// The denormals-are-zeros mode was introduced in the Pentium 4 and Intel Xeon processor with the SSE2 extensions; however, it is fully compatible with the SSE SIMD floating-point instructions
/// (that is, the denormals-are-zeros flag affects the operation of the SSE SIMD floating-point instructions). In earlier IA-32 processors and in some models of the Pentium 4 processor, this flag
/// (bit 6) is reserved. Attempting to set bit 6 of the MXCSR register on processors that do not support the DAZ flag will cause a general-protection exception (#GP).
/// </remarks>
DenormalsAreZeroes = 1 << 6,
/// <summary>Bits 0 through 5 of the MXCSR register indicate whether a SIMD floating-point exception has been detected. They are "sticky" flags. That is, after a flag is set, it remains set until explicitly cleared. To clear these flags, use the LDMXCSR or the FXRSTOR instruction to write zeroes to them.</summary>
PrecisionFlag = 1 << 5,
/// <summary>Bits 0 through 5 of the MXCSR register indicate whether a SIMD floating-point exception has been detected. They are "sticky" flags. That is, after a flag is set, it remains set until explicitly cleared. To clear these flags, use the LDMXCSR or the FXRSTOR instruction to write zeroes to them.</summary>
UnderflowFlag = 1 << 4,
/// <summary>Bits 0 through 5 of the MXCSR register indicate whether a SIMD floating-point exception has been detected. They are "sticky" flags. That is, after a flag is set, it remains set until explicitly cleared. To clear these flags, use the LDMXCSR or the FXRSTOR instruction to write zeroes to them.</summary>
OverflowFlag = 1 << 3,
/// <summary>Bits 0 through 5 of the MXCSR register indicate whether a SIMD floating-point exception has been detected. They are "sticky" flags. That is, after a flag is set, it remains set until explicitly cleared. To clear these flags, use the LDMXCSR or the FXRSTOR instruction to write zeroes to them.</summary>
DivideByZeroFlag = 1 << 2,
/// <summary>Bits 0 through 5 of the MXCSR register indicate whether a SIMD floating-point exception has been detected. They are "sticky" flags. That is, after a flag is set, it remains set until explicitly cleared. To clear these flags, use the LDMXCSR or the FXRSTOR instruction to write zeroes to them.</summary>
DenormalFlag = 1 << 1,
/// <summary>Bits 0 through 5 of the MXCSR register indicate whether a SIMD floating-point exception has been detected. They are "sticky" flags. That is, after a flag is set, it remains set until explicitly cleared. To clear these flags, use the LDMXCSR or the FXRSTOR instruction to write zeroes to them.</summary>
InvalidOperationFlag = 1 << 0,
/// <summary>
/// Combines all bits for flags into one mask for convenience.
/// </summary>
FlagMask = PrecisionFlag | UnderflowFlag | OverflowFlag | DivideByZeroFlag | DenormalFlag | InvalidOperationFlag,
}
/// <summary>
/// Rounding mode flags
/// </summary>
[Flags]
public enum RoundingMode
{
/// <summary>
/// Round to the nearest integer
/// </summary>
FROUND_TO_NEAREST_INT = 0x00,
/// <summary>
/// Round to negative infinity
/// </summary>
FROUND_TO_NEG_INF = 0x01,
/// <summary>
/// Round to positive infinity
/// </summary>
FROUND_TO_POS_INF = 0x02,
/// <summary>
/// Round to zero
/// </summary>
FROUND_TO_ZERO = 0x03,
/// <summary>
/// Round to current direction
/// </summary>
FROUND_CUR_DIRECTION = 0x04,
/// <summary>
/// Do not suppress exceptions
/// </summary>
FROUND_RAISE_EXC = 0x00,
/// <summary>
/// Suppress exceptions
/// </summary>
FROUND_NO_EXC = 0x08,
/// <summary>
/// Round to the nearest integer without suppressing exceptions
/// </summary>
FROUND_NINT = FROUND_TO_NEAREST_INT | FROUND_RAISE_EXC,
/// <summary>
/// Round using Floor function without suppressing exceptions
/// </summary>
FROUND_FLOOR = FROUND_TO_NEG_INF | FROUND_RAISE_EXC,
/// <summary>
/// Round using Ceiling function without suppressing exceptions
/// </summary>
FROUND_CEIL = FROUND_TO_POS_INF | FROUND_RAISE_EXC,
/// <summary>
/// Round by truncating without suppressing exceptions
/// </summary>
FROUND_TRUNC = FROUND_TO_ZERO | FROUND_RAISE_EXC,
/// <summary>
/// Round using MXCSR.RC without suppressing exceptions
/// </summary>
FROUND_RINT = FROUND_CUR_DIRECTION | FROUND_RAISE_EXC,
/// <summary>
/// Round using MXCSR.RC and suppressing exceptions
/// </summary>
FROUND_NEARBYINT = FROUND_CUR_DIRECTION | FROUND_NO_EXC,
/// <summary>
/// Round to nearest integer and suppressing exceptions
/// </summary>
FROUND_NINT_NOEXC = FROUND_TO_NEAREST_INT | FROUND_NO_EXC,
/// <summary>
/// Round using Floor function and suppressing exceptions
/// </summary>
FROUND_FLOOR_NOEXC = FROUND_TO_NEG_INF | FROUND_NO_EXC,
/// <summary>
/// Round using Ceiling function and suppressing exceptions
/// </summary>
FROUND_CEIL_NOEXC = FROUND_TO_POS_INF | FROUND_NO_EXC,
/// <summary>
/// Round by truncating and suppressing exceptions
/// </summary>
FROUND_TRUNC_NOEXC = FROUND_TO_ZERO | FROUND_NO_EXC,
/// <summary>
/// Round using MXCSR.RC and suppressing exceptions
/// </summary>
FROUND_RINT_NOEXC = FROUND_CUR_DIRECTION | FROUND_NO_EXC,
}
internal struct RoundingScope : IDisposable
{
private MXCSRBits OldBits;
public RoundingScope(MXCSRBits roundingMode)
{
OldBits = MXCSR;
MXCSR = (OldBits & ~MXCSRBits.RoundingControlMask) | roundingMode;
}
public void Dispose()
{
MXCSR = OldBits;
}
}
#if !BURST_INTERNAL
private static void BurstIntrinsicSetCSRFromManaged(int _) { }
private static int BurstIntrinsicGetCSRFromManaged() { return 0; }
internal static int getcsr_raw() => DoGetCSRTrampoline();
internal static void setcsr_raw(int bits) => DoSetCSRTrampoline(bits);
[BurstCompile(CompileSynchronously = true)]
private static void DoSetCSRTrampoline(int bits)
{
if (Sse.IsSseSupported)
BurstIntrinsicSetCSRFromManaged(bits);
}
[BurstCompile(CompileSynchronously = true)]
private static int DoGetCSRTrampoline()
{
if (Sse.IsSseSupported)
return BurstIntrinsicGetCSRFromManaged();
return 0;
}
#elif BURST_INTERNAL
// Internally inside burst for unit tests we can't recurse from tests into burst again,
// so we pinvoke to a dummy wrapper DLL that exposes CSR manipulation
[DllImport("burst-dllimport-native", EntryPoint = "x86_getcsr")]
internal static extern int getcsr_raw();
[DllImport("burst-dllimport-native", EntryPoint = "x86_setcsr")]
internal static extern void setcsr_raw(int bits);
#endif
/// <summary>
/// Allows access to the CSR register
/// </summary>
public static MXCSRBits MXCSR
{
[BurstTargetCpu(BurstTargetCpu.X64_SSE2)]
get
{
return (MXCSRBits)getcsr_raw();
}
[BurstTargetCpu(BurstTargetCpu.X64_SSE2)]
set
{
setcsr_raw((int)value);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b88ec138634e3238a82a5b8f3d970ac1
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,306 @@
using System.Diagnostics;
namespace Unity.Burst.Intrinsics
{
public unsafe static partial class X86
{
/// <summary>
/// F16C intrinsics
/// </summary>
public static class F16C
{
/// <summary>
/// Evaluates to true at compile time if F16C intrinsics are supported.
///
/// Burst ties F16C support to AVX2 support to simplify feature sets to support.
/// </summary>
public static bool IsF16CSupported { get { return Avx2.IsAvx2Supported; } }
/// <summary>
/// Converts a half (hiding in a ushort) to a float (hiding in a uint).
/// </summary>
/// <param name="h">The half to convert</param>
/// <returns>The float result</returns>
[DebuggerStepThrough]
private static uint HalfToFloat(ushort h)
{
var signed = (h & 0x8000u) != 0;
var exponent = (h >> 10) & 0x1fu;
var mantissa = h & 0x3ffu;
var result = signed ? 0x80000000u : 0u;
if (!(exponent == 0 && mantissa == 0))
{
// Denormal (converts to normalized)
if (exponent == 0)
{
// Adjust mantissa so it's normalized (and keep track of exponent adjustment)
exponent = -1;
do
{
exponent++;
mantissa <<= 1;
} while ((mantissa & 0x400) == 0);
result |= (uint)((127 - 15 - exponent) << 23);
// Have to re-mask the mantissa here because we've been shifting bits up.
result |= (mantissa & 0x3ff) << 13;
}
else
{
var isInfOrNan = exponent == 0x1f;
result |= (uint)(isInfOrNan ? 255 : (127 - 15 + exponent) << 23);
result |= mantissa << 13;
}
}
return result;
}
/// <summary>
/// Convert packed half-precision (16-bit) floating-point elements in a to packed single-precision (32-bit) floating-point elements, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vcvtph2ps xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 cvtph_ps(v128 a)
{
return new v128(HalfToFloat(a.UShort0), HalfToFloat(a.UShort1), HalfToFloat(a.UShort2), HalfToFloat(a.UShort3));
}
/// <summary>
/// Convert packed half-precision (16-bit) floating-point elements in a to packed single-precision (32-bit) floating-point elements, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vcvtph2ps ymm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v256 mm256_cvtph_ps(v128 a)
{
return new v256(HalfToFloat(a.UShort0), HalfToFloat(a.UShort1), HalfToFloat(a.UShort2), HalfToFloat(a.UShort3), HalfToFloat(a.UShort4), HalfToFloat(a.UShort5), HalfToFloat(a.UShort6), HalfToFloat(a.UShort7));
}
// Using ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf
private static readonly ushort[] BaseTable =
{
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
0x0200, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00,
0x4000, 0x4400, 0x4800, 0x4C00, 0x5000, 0x5400, 0x5800, 0x5C00, 0x6000, 0x6400, 0x6800, 0x6C00, 0x7000, 0x7400, 0x7800, 0x7C00,
0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001, 0x8002, 0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100,
0x8200, 0x8400, 0x8800, 0x8C00, 0x9000, 0x9400, 0x9800, 0x9C00, 0xA000, 0xA400, 0xA800, 0xAC00, 0xB000, 0xB400, 0xB800, 0xBC00,
0xC000, 0xC400, 0xC800, 0xCC00, 0xD000, 0xD400, 0xD800, 0xDC00, 0xE000, 0xE400, 0xE800, 0xEC00, 0xF000, 0xF400, 0xF800, 0xFC00,
0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
};
private static readonly sbyte[] ShiftTable =
{
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 13,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 13,
};
/// <summary>
/// Converts a float (hiding in a uint) to a half (hiding in a ushort).
/// </summary>
/// <param name="f">The float to convert</param>
/// <param name="rounding">Rounding mode</param>
/// <returns>The half result</returns>
[DebuggerStepThrough]
private static ushort FloatToHalf(uint f, int rounding)
{
var exponentAndSign = f >> 23;
var shift = ShiftTable[exponentAndSign];
var result = (uint)(BaseTable[exponentAndSign] + (ushort)((f & 0x7FFFFFu) >> shift));
// Check if the result is not Inf or NaN.
var isFinite = (result & 0x7C00) != 0x7C00;
var isNegative = (result & 0x8000) != 0;
if (rounding == (int)RoundingMode.FROUND_NINT_NOEXC)
{
var fWithRoundingBitPreserved = (f & 0x7FFFFFu) >> (shift - 1);
if ((exponentAndSign & 0xFF) == 102)
{
result++;
}
if (isFinite && ((fWithRoundingBitPreserved & 0x1u) != 0))
{
result++;
}
}
else if (rounding == (int)RoundingMode.FROUND_TRUNC_NOEXC)
{
if (!isFinite)
{
result -= (uint)(~shift & 0x1);
}
}
else if (rounding == (int)RoundingMode.FROUND_CEIL_NOEXC)
{
if (isFinite && !isNegative)
{
if ((exponentAndSign <= 102) && (exponentAndSign != 0))
{
result++;
}
else if ((f & 0x7FFFFFu & ((1u << shift) - 1u)) != 0)
{
result++;
}
}
var resultIsNegativeInf = (result == 0xFC00);
var inputIsNotNegativeInfOrNan = (exponentAndSign != 0x1FF);
if (resultIsNegativeInf && inputIsNotNegativeInfOrNan)
{
result--;
}
}
else if (rounding == (int)RoundingMode.FROUND_FLOOR_NOEXC)
{
if (isFinite && isNegative)
{
if ((exponentAndSign <= 358) && (exponentAndSign != 256))
{
result++;
}
else if ((f & 0x7FFFFFu & ((1u << shift) - 1u)) != 0)
{
result++;
}
}
var resultIsPositiveInf = (result == 0x7C00);
var inputIsNotPositiveInfOrNan = (exponentAndSign != 0xFF);
if (resultIsPositiveInf && inputIsNotPositiveInfOrNan)
{
result--;
}
}
return (ushort)result;
}
/// <summary>
/// Convert packed single-precision (32-bit) floating-point elements in a to packed half-precision (16-bit) floating-point elements, and store the results in dst.
///
/// Rounding is done according to the rounding parameter, which can be one of:
/// </summary>
/// <remarks>
/// **** cvtps2ph xmm, xmm, imm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="rounding">Rounding mode</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 cvtps_ph(v128 a, int rounding)
{
if (rounding == (int)RoundingMode.FROUND_RINT_NOEXC)
{
switch (MXCSR & MXCSRBits.RoundingControlMask)
{
case MXCSRBits.RoundToNearest:
rounding = (int)RoundingMode.FROUND_NINT_NOEXC;
break;
case MXCSRBits.RoundDown:
rounding = (int)RoundingMode.FROUND_FLOOR_NOEXC;
break;
case MXCSRBits.RoundUp:
rounding = (int)RoundingMode.FROUND_CEIL_NOEXC;
break;
case MXCSRBits.RoundTowardZero:
rounding = (int)RoundingMode.FROUND_TRUNC_NOEXC;
break;
}
}
return new v128(FloatToHalf(a.UInt0, rounding), FloatToHalf(a.UInt1, rounding), FloatToHalf(a.UInt2, rounding), FloatToHalf(a.UInt3, rounding), 0, 0, 0, 0);
}
/// <summary>
/// Convert packed single-precision (32-bit) floating-point elements in a to packed half-precision (16-bit) floating-point elements, and store the results in dst.
///
/// Rounding is done according to the rounding parameter, which can be one of:
/// </summary>
/// <remarks>
/// **** cvtps2ph xmm, ymm, imm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="rounding">Rounding mode</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 mm256_cvtps_ph(v256 a, int rounding)
{
if (rounding == (int)RoundingMode.FROUND_RINT_NOEXC)
{
switch (MXCSR & MXCSRBits.RoundingControlMask)
{
case MXCSRBits.RoundToNearest:
rounding = (int)RoundingMode.FROUND_NINT_NOEXC;
break;
case MXCSRBits.RoundDown:
rounding = (int)RoundingMode.FROUND_FLOOR_NOEXC;
break;
case MXCSRBits.RoundUp:
rounding = (int)RoundingMode.FROUND_CEIL_NOEXC;
break;
case MXCSRBits.RoundTowardZero:
rounding = (int)RoundingMode.FROUND_TRUNC_NOEXC;
break;
}
}
return new v128(FloatToHalf(a.UInt0, rounding), FloatToHalf(a.UInt1, rounding), FloatToHalf(a.UInt2, rounding), FloatToHalf(a.UInt3, rounding), FloatToHalf(a.UInt4, rounding), FloatToHalf(a.UInt5, rounding), FloatToHalf(a.UInt6, rounding), FloatToHalf(a.UInt7, rounding));
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ae12ed22401338869b648a8327f251da
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,624 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Unity.Burst.Intrinsics
{
public unsafe static partial class X86
{
/// <summary>
/// FMA intrinsics
/// </summary>
public static class Fma
{
/// <summary>
/// Evaluates to true at compile time if FMA intrinsics are supported.
///
/// Burst ties FMA support to AVX2 support to simplify feature sets to support.
/// </summary>
public static bool IsFmaSupported { get { return Avx2.IsAvx2Supported; } }
[DebuggerStepThrough]
private static float FmaHelper(float a, float b, float c)
{
return (float)((((double)a) * b) + c);
}
[StructLayout(LayoutKind.Explicit)]
private struct Union
{
[FieldOffset(0)]
public float f;
[FieldOffset(0)]
public uint u;
}
[DebuggerStepThrough]
private static float FnmaHelper(float a, float b, float c)
{
return FmaHelper(-a, b, c);
}
/// <summary>
/// Multiply packed double-precision (64-bit) floating-point elements in a and b, add the intermediate result to packed elements in c, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfmadd213pd xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fmadd_pd(v128 a, v128 b, v128 c)
{
throw new Exception("Double-precision FMA not emulated in C#");
}
/// <summary>
/// Multiply packed double-precision (64-bit) floating-point elements in a and b, add the intermediate result to packed elements in c, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfmadd213pd ymm, ymm, ymm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v256 mm256_fmadd_pd(v256 a, v256 b, v256 c)
{
throw new Exception("Double-precision FMA not emulated in C#");
}
/// <summary>
/// Multiply packed single-precision (32-bit) floating-point elements in a and b, add the intermediate result to packed elements in c, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfmadd213ps xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fmadd_ps(v128 a, v128 b, v128 c)
{
return new v128(FmaHelper(a.Float0, b.Float0, c.Float0),
FmaHelper(a.Float1, b.Float1, c.Float1),
FmaHelper(a.Float2, b.Float2, c.Float2),
FmaHelper(a.Float3, b.Float3, c.Float3));
}
/// <summary>
/// Multiply packed single-precision (32-bit) floating-point elements in a and b, add the intermediate result to packed elements in c, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfmadd213ps ymm, ymm, ymm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v256 mm256_fmadd_ps(v256 a, v256 b, v256 c)
{
return new v256(FmaHelper(a.Float0, b.Float0, c.Float0),
FmaHelper(a.Float1, b.Float1, c.Float1),
FmaHelper(a.Float2, b.Float2, c.Float2),
FmaHelper(a.Float3, b.Float3, c.Float3),
FmaHelper(a.Float4, b.Float4, c.Float4),
FmaHelper(a.Float5, b.Float5, c.Float5),
FmaHelper(a.Float6, b.Float6, c.Float6),
FmaHelper(a.Float7, b.Float7, c.Float7));
}
/// <summary>
/// Multiply the lower double-precision (64-bit) floating-point elements in a and b, and add the intermediate result to the lower element in c. Store the result in the lower element of dst, and copy the upper element from a to the upper element of dst.
/// </summary>
/// <remarks>
/// **** vfmadd213sd xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fmadd_sd(v128 a, v128 b, v128 c)
{
throw new Exception("Double-precision FMA not emulated in C#");
}
/// <summary>
/// Multiply the lower single-precision (32-bit) floating-point elements in a and b, and add the intermediate result to the lower element in c. Store the result in the lower element of dst, and copy the upper 3 packed elements from a to the upper elements of dst.
/// </summary>
/// <remarks>
/// **** vfmadd213ss xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fmadd_ss(v128 a, v128 b, v128 c)
{
var result = a;
result.Float0 = FmaHelper(a.Float0, b.Float0, c.Float0);
return result;
}
/// <summary>
/// Multiply packed double-precision (64-bit) floating-point elements in a and b, alternatively add and subtract packed elements in c to/from the intermediate result, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfmaddsub213pd xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fmaddsub_pd(v128 a, v128 b, v128 c)
{
throw new Exception("Double-precision FMA not emulated in C#");
}
/// <summary>
/// Multiply packed double-precision (64-bit) floating-point elements in a and b, alternatively add and subtract packed elements in c to/from the intermediate result, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfmaddsub213pd ymm, ymm, ymm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v256 mm256_fmaddsub_pd(v256 a, v256 b, v256 c)
{
throw new Exception("Double-precision FMA not emulated in C#");
}
/// <summary>
/// Multiply packed single-precision (32-bit) floating-point elements in a and b, alternatively add and subtract packed elements in c to/from the intermediate result, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfmaddsub213ps xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fmaddsub_ps(v128 a, v128 b, v128 c)
{
return new v128(FmaHelper(a.Float0, b.Float0, -c.Float0),
FmaHelper(a.Float1, b.Float1, c.Float1),
FmaHelper(a.Float2, b.Float2, -c.Float2),
FmaHelper(a.Float3, b.Float3, c.Float3));
}
/// <summary>
/// Multiply packed single-precision (32-bit) floating-point elements in a and b, alternatively add and subtract packed elements in c to/from the intermediate result, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfmaddsub213ps ymm, ymm, ymm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v256 mm256_fmaddsub_ps(v256 a, v256 b, v256 c)
{
return new v256(FmaHelper(a.Float0, b.Float0, -c.Float0),
FmaHelper(a.Float1, b.Float1, c.Float1),
FmaHelper(a.Float2, b.Float2, -c.Float2),
FmaHelper(a.Float3, b.Float3, c.Float3),
FmaHelper(a.Float4, b.Float4, -c.Float4),
FmaHelper(a.Float5, b.Float5, c.Float5),
FmaHelper(a.Float6, b.Float6, -c.Float6),
FmaHelper(a.Float7, b.Float7, c.Float7));
}
/// <summary>
/// Multiply packed double-precision (64-bit) floating-point elements in a and b, subtract packed elements in c from the intermediate result, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfmsub213pd xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fmsub_pd(v128 a, v128 b, v128 c)
{
throw new Exception("Double-precision FMA not emulated in C#");
}
/// <summary>
/// Multiply packed double-precision (64-bit) floating-point elements in a and b, subtract packed elements in c from the intermediate result, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfmsub213pd ymm, ymm, ymm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v256 mm256_fmsub_pd(v256 a, v256 b, v256 c)
{
throw new Exception("Double-precision FMA not emulated in C#");
}
/// <summary>
/// Multiply packed single-precision (32-bit) floating-point elements in a and b, subtract packed elements in c from the intermediate result, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfmsub213ps xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fmsub_ps(v128 a, v128 b, v128 c)
{
return new v128(FmaHelper(a.Float0, b.Float0, -c.Float0),
FmaHelper(a.Float1, b.Float1, -c.Float1),
FmaHelper(a.Float2, b.Float2, -c.Float2),
FmaHelper(a.Float3, b.Float3, -c.Float3));
}
/// <summary>
/// Multiply packed single-precision (32-bit) floating-point elements in a and b, subtract packed elements in c from the intermediate result, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfmsub213ps ymm, ymm, ymm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v256 mm256_fmsub_ps(v256 a, v256 b, v256 c)
{
return new v256(FmaHelper(a.Float0, b.Float0, -c.Float0),
FmaHelper(a.Float1, b.Float1, -c.Float1),
FmaHelper(a.Float2, b.Float2, -c.Float2),
FmaHelper(a.Float3, b.Float3, -c.Float3),
FmaHelper(a.Float4, b.Float4, -c.Float4),
FmaHelper(a.Float5, b.Float5, -c.Float5),
FmaHelper(a.Float6, b.Float6, -c.Float6),
FmaHelper(a.Float7, b.Float7, -c.Float7));
}
/// <summary>
/// Multiply the lower double-precision(64-bit) floating-point elements in a and b, and subtract the lower element in c from the intermediate result.Store the result in the lower element of dst, and copy the upper element from a to the upper element of dst.
/// </summary>
/// <remarks>
/// **** vfmsub213sd xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fmsub_sd(v128 a, v128 b, v128 c)
{
throw new Exception("Double-precision FMA not emulated in C#");
}
/// <summary>
/// Multiply the lower single-precision (32-bit) floating-point elements in a and b, and subtract the lower element in c from the intermediate result. Store the result in the lower element of dst, and copy the upper 3 packed elements from a to the upper elements of dst.
/// </summary>
/// <remarks>
/// **** vfmsub213ss xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fmsub_ss(v128 a, v128 b, v128 c)
{
var result = a;
result.Float0 = FmaHelper(a.Float0, b.Float0, -c.Float0);
return result;
}
/// <summary>
/// Multiply packed double-precision (64-bit) floating-point elements in a and b, alternatively subtract and add packed elements in c to/from the intermediate result, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfmsubadd213pd xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fmsubadd_pd(v128 a, v128 b, v128 c)
{
throw new Exception("Double-precision FMA not emulated in C#");
}
/// <summary>
/// Multiply packed double-precision (64-bit) floating-point elements in a and b, alternatively subtract and add packed elements in c to/from the intermediate result, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfmsubadd213pd ymm, ymm, ymm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v256 mm256_fmsubadd_pd(v256 a, v256 b, v256 c)
{
throw new Exception("Double-precision FMA not emulated in C#");
}
/// <summary>
/// Multiply packed single-precision (32-bit) floating-point elements in a and b, alternatively subtract and add packed elements in c to/from the intermediate result, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfmsubadd213ps xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fmsubadd_ps(v128 a, v128 b, v128 c)
{
return new v128(FmaHelper(a.Float0, b.Float0, c.Float0),
FmaHelper(a.Float1, b.Float1, -c.Float1),
FmaHelper(a.Float2, b.Float2, c.Float2),
FmaHelper(a.Float3, b.Float3, -c.Float3));
}
/// <summary>
/// Multiply packed single-precision (32-bit) floating-point elements in a and b, alternatively subtract and add packed elements in c to/from the intermediate result, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfmsubadd213ps ymm, ymm, ymm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v256 mm256_fmsubadd_ps(v256 a, v256 b, v256 c)
{
return new v256(FmaHelper(a.Float0, b.Float0, c.Float0),
FmaHelper(a.Float1, b.Float1, -c.Float1),
FmaHelper(a.Float2, b.Float2, c.Float2),
FmaHelper(a.Float3, b.Float3, -c.Float3),
FmaHelper(a.Float4, b.Float4, c.Float4),
FmaHelper(a.Float5, b.Float5, -c.Float5),
FmaHelper(a.Float6, b.Float6, c.Float6),
FmaHelper(a.Float7, b.Float7, -c.Float7));
}
/// <summary>
/// Multiply packed double-precision (64-bit) floating-point elements in a and b, add the negated intermediate result to packed elements in c, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfnmadd213pd xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fnmadd_pd(v128 a, v128 b, v128 c)
{
throw new Exception("Double-precision FMA not emulated in C#");
}
/// <summary>
/// Multiply packed double-precision (64-bit) floating-point elements in a and b, add the negated intermediate result to packed elements in c, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfnmadd213pd ymm, ymm, ymm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v256 mm256_fnmadd_pd(v256 a, v256 b, v256 c)
{
throw new Exception("Double-precision FMA not emulated in C#");
}
/// <summary>
/// Multiply packed single-precision (32-bit) floating-point elements in a and b, add the negated intermediate result to packed elements in c, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfnmadd213ps xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fnmadd_ps(v128 a, v128 b, v128 c)
{
return new v128(FnmaHelper(a.Float0, b.Float0, c.Float0),
FnmaHelper(a.Float1, b.Float1, c.Float1),
FnmaHelper(a.Float2, b.Float2, c.Float2),
FnmaHelper(a.Float3, b.Float3, c.Float3));
}
/// <summary>
/// Multiply packed single-precision (32-bit) floating-point elements in a and b, add the negated intermediate result to packed elements in c, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfnmadd213ps ymm, ymm, ymm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v256 mm256_fnmadd_ps(v256 a, v256 b, v256 c)
{
return new v256(FnmaHelper(a.Float0, b.Float0, c.Float0),
FnmaHelper(a.Float1, b.Float1, c.Float1),
FnmaHelper(a.Float2, b.Float2, c.Float2),
FnmaHelper(a.Float3, b.Float3, c.Float3),
FnmaHelper(a.Float4, b.Float4, c.Float4),
FnmaHelper(a.Float5, b.Float5, c.Float5),
FnmaHelper(a.Float6, b.Float6, c.Float6),
FnmaHelper(a.Float7, b.Float7, c.Float7));
}
/// <summary>
/// Multiply the lower double-precision (64-bit) floating-point elements in a and b, and add the negated intermediate result to the lower element in c. Store the result in the lower element of dst, and copy the upper element from a to the upper element of dst.
/// </summary>
/// <remarks>
/// **** vfnmadd213sd xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fnmadd_sd(v128 a, v128 b, v128 c)
{
throw new Exception("Double-precision FMA not emulated in C#");
}
/// <summary>
/// Multiply the lower single-precision (32-bit) floating-point elements in a and b, and add the negated intermediate result to the lower element in c. Store the result in the lower element of dst, and copy the upper 3 packed elements from a to the upper elements of dst.
/// </summary>
/// <remarks>
/// **** vfnmadd213ss xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fnmadd_ss(v128 a, v128 b, v128 c)
{
var result = a;
result.Float0 = FnmaHelper(a.Float0, b.Float0, c.Float0);
return result;
}
/// <summary>
/// Multiply packed double-precision (64-bit) floating-point elements in a and b, subtract packed elements in c from the negated intermediate result, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfnmsub213pd xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fnmsub_pd(v128 a, v128 b, v128 c)
{
throw new Exception("Double-precision FMA not emulated in C#");
}
/// <summary>
/// Multiply packed double-precision (64-bit) floating-point elements in a and b, subtract packed elements in c from the negated intermediate result, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfnmsub213pd ymm, ymm, ymm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v256 mm256_fnmsub_pd(v256 a, v256 b, v256 c)
{
throw new Exception("Double-precision FMA not emulated in C#");
}
/// <summary>
/// Multiply packed single-precision (32-bit) floating-point elements in a and b, subtract packed elements in c from the negated intermediate result, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfnmsub213ps xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fnmsub_ps(v128 a, v128 b, v128 c)
{
return new v128(FnmaHelper(a.Float0, b.Float0, -c.Float0),
FnmaHelper(a.Float1, b.Float1, -c.Float1),
FnmaHelper(a.Float2, b.Float2, -c.Float2),
FnmaHelper(a.Float3, b.Float3, -c.Float3));
}
/// <summary>
/// Multiply packed single-precision (32-bit) floating-point elements in a and b, subtract packed elements in c from the negated intermediate result, and store the results in dst.
/// </summary>
/// <remarks>
/// **** vfnmsub213ps ymm, ymm, ymm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v256 mm256_fnmsub_ps(v256 a, v256 b, v256 c)
{
return new v256(FnmaHelper(a.Float0, b.Float0, -c.Float0),
FnmaHelper(a.Float1, b.Float1, -c.Float1),
FnmaHelper(a.Float2, b.Float2, -c.Float2),
FnmaHelper(a.Float3, b.Float3, -c.Float3),
FnmaHelper(a.Float4, b.Float4, -c.Float4),
FnmaHelper(a.Float5, b.Float5, -c.Float5),
FnmaHelper(a.Float6, b.Float6, -c.Float6),
FnmaHelper(a.Float7, b.Float7, -c.Float7));
}
/// <summary>
/// Multiply the lower double-precision(64-bit) floating-point elements in a and b, and subtract the lower element in c from the negated intermediate result.Store the result in the lower element of dst, and copy the upper element from a to the upper element of dst.
/// </summary>
/// <remarks>
/// **** vfnmsub213sd xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fnmsub_sd(v128 a, v128 b, v128 c)
{
throw new Exception("Double-precision FMA not emulated in C#");
}
/// <summary>
/// Multiply the lower single-precision (32-bit) floating-point elements in a and b, and subtract the lower element in c from the negated intermediate result. Store the result in the lower element of dst, and copy the upper 3 packed elements from a to the upper elements of dst.
/// </summary>
/// <remarks>
/// **** vfnmsub213ss xmm, xmm, xmm
/// </remarks>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="c">Vector c</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 fnmsub_ss(v128 a, v128 b, v128 c)
{
var result = a;
result.Float0 = FnmaHelper(a.Float0, b.Float0, -c.Float0);
return result;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4d7325591616354d86b1492e282843f4
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,62 @@
using System.Diagnostics;
namespace Unity.Burst.Intrinsics
{
public unsafe static partial class X86
{
/// <summary>
/// popcnt intrinsics
/// </summary>
public static class Popcnt
{
/// <summary>
/// Evaluates to true at compile time if popcnt intrinsics are supported.
///
/// Burst ties popcnt support to SSE4.2 support to simplify feature sets to support.
/// </summary>
public static bool IsPopcntSupported { get { return Sse4_2.IsSse42Supported; } }
/// <summary>
/// Count the number of bits set to 1 in unsigned 32-bit integer a, and return that count in dst.
/// </summary>
/// <remarks>
/// **** popcnt r32, r32
/// </remarks>
/// <param name="v">Integer to be counted in</param>
/// <returns>Count</returns>
[DebuggerStepThrough]
public static int popcnt_u32(uint v)
{
int result = 0;
uint mask = 0x80000000u;
while (mask != 0)
{
result += ((v & mask) != 0) ? 1 : 0;
mask >>= 1;
}
return result;
}
/// <summary>
/// Count the number of bits set to 1 in unsigned 64-bit integer a, and return that count in dst.
/// </summary>
/// <remarks>
/// **** popcnt r64, r64
/// </remarks>
/// <param name="v">Integer to be counted in</param>
/// <returns>Count</returns>
[DebuggerStepThrough]
public static int popcnt_u64(ulong v)
{
int result = 0;
ulong mask = 0x8000000000000000u;
while (mask != 0)
{
result += ((v & mask) != 0) ? 1 : 0;
mask >>= 1;
}
return result;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e4725d04fd6336efbc80f25ae908c344
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9edae0ecbfb63f239983f9a81f80ddf9
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f0de54c00de3304699fdf0bedf123944
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,155 @@
using System;
using System.Diagnostics;
namespace Unity.Burst.Intrinsics
{
public unsafe static partial class X86
{
/// <summary>
/// SSE3 intrinsics
/// </summary>
public static class Sse3
{
/// <summary>
/// Evaluates to true at compile time if SSE3 intrinsics are supported.
/// </summary>
public static bool IsSse3Supported { get { return false; } }
// _mm_addsub_ps
/// <summary> Alternatively add and subtract packed single-precision (32-bit) floating-point elements in "a" to/from packed elements in "b", and store the results in "dst". </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 addsub_ps(v128 a, v128 b)
{
v128 dst = default(v128);
dst.Float0 = a.Float0 - b.Float0;
dst.Float1 = a.Float1 + b.Float1;
dst.Float2 = a.Float2 - b.Float2;
dst.Float3 = a.Float3 + b.Float3;
return dst;
}
// _mm_addsub_pd
/// <summary> Alternatively add and subtract packed double-precision (64-bit) floating-point elements in "a" to/from packed elements in "b", and store the results in "dst". </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 addsub_pd(v128 a, v128 b)
{
v128 dst = default(v128);
dst.Double0 = a.Double0 - b.Double0;
dst.Double1 = a.Double1 + b.Double1;
return dst;
}
// _mm_hadd_pd
/// <summary> Horizontally add adjacent pairs of double-precision (64-bit) floating-point elements in "a" and "b", and pack the results in "dst". </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 hadd_pd(v128 a, v128 b)
{
v128 dst = default(v128);
dst.Double0 = a.Double0 + a.Double1;
dst.Double1 = b.Double0 + b.Double1;
return dst;
}
// _mm_hadd_ps
/// <summary> Horizontally add adjacent pairs of single-precision (32-bit) floating-point elements in "a" and "b", and pack the results in "dst". </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 hadd_ps(v128 a, v128 b)
{
v128 dst = default(v128);
dst.Float0 = a.Float0 + a.Float1;
dst.Float1 = a.Float2 + a.Float3;
dst.Float2 = b.Float0 + b.Float1;
dst.Float3 = b.Float2 + b.Float3;
return dst;
}
// _mm_hsub_pd
/// <summary> Horizontally subtract adjacent pairs of double-precision (64-bit) floating-point elements in "a" and "b", and pack the results in "dst". </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 hsub_pd(v128 a, v128 b)
{
v128 dst = default(v128);
dst.Double0 = a.Double0 - a.Double1;
dst.Double1 = b.Double0 - b.Double1;
return dst;
}
// _mm_hsub_ps
/// <summary> Horizontally add adjacent pairs of single-precision (32-bit) floating-point elements in "a" and "b", and pack the results in "dst". </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 hsub_ps(v128 a, v128 b)
{
v128 dst = default(v128);
dst.Float0 = a.Float0 - a.Float1;
dst.Float1 = a.Float2 - a.Float3;
dst.Float2 = b.Float0 - b.Float1;
dst.Float3 = b.Float2 - b.Float3;
return dst;
}
// _mm_movedup_pd
/// <summary> Duplicate the low double-precision (64-bit) floating-point element from "a", and store the results in "dst". </summary>
/// <param name="a">Vector a</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 movedup_pd(v128 a)
{
// Burst IR is fine
v128 dst = default(v128);
dst.Double0 = a.Double0;
dst.Double1 = a.Double0;
return dst;
}
// _mm_movehdup_ps
/// <summary> Duplicate odd-indexed single-precision (32-bit) floating-point elements from "a", and store the results in "dst". </summary>
/// <param name="a">Vector a</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 movehdup_ps(v128 a)
{
// Burst IR is fine
v128 dst = default(v128);
dst.Float0 = a.Float1;
dst.Float1 = a.Float1;
dst.Float2 = a.Float3;
dst.Float3 = a.Float3;
return dst;
}
// _mm_moveldup_ps
/// <summary> Duplicate even-indexed single-precision (32-bit) floating-point elements from "a", and store the results in "dst". </summary>
/// <param name="a">Vector a</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 moveldup_ps(v128 a)
{
// Burst IR is fine
v128 dst = default(v128);
dst.Float0 = a.Float0;
dst.Float1 = a.Float0;
dst.Float2 = a.Float2;
dst.Float3 = a.Float2;
return dst;
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More