diff --git a/Runtime/AssemblyInfo.cs b/Runtime/AssemblyInfo.cs index 1ea114b..0a91020 100644 --- a/Runtime/AssemblyInfo.cs +++ b/Runtime/AssemblyInfo.cs @@ -32,9 +32,9 @@ // Build Number // Revision // -[assembly: AssemblyVersion("2.3.0")] -[assembly: AssemblyFileVersion("2.3.0")] -[assembly: AssemblyInformationalVersion("2.3 Release")] +[assembly: AssemblyVersion("2.3.5")] +[assembly: AssemblyFileVersion("2.3.5")] +[assembly: AssemblyInformationalVersion("2.3.5 Release")] [assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Unity.Mathematics API consistency")] [assembly: CompilationRelaxationsAttribute(CompilationRelaxations.NoStringInterning)] \ No newline at end of file diff --git a/Runtime/Math Lib/Constants.cs b/Runtime/Math Lib/Constants.cs index c5843a2..17aa5ee 100644 --- a/Runtime/Math Lib/Constants.cs +++ b/Runtime/Math Lib/Constants.cs @@ -11,6 +11,9 @@ unsafe public static partial class maxmath /// The square root 3. Approximately 1.73. This is a f64/double precision constant. public const double SQRT3_DBL = 1.73205080756887729352d; + /// The square root 5. Approximately 2.23. This is a f64/double precision constant. + public const double SQRT5_DBL = 2.23606797749978969640d; + /// The cube root of 2. Approximately 1.26. This is a f64/double precision constant. public const double CBRT2_DBL = 1.25992104989487316476d; @@ -27,6 +30,9 @@ unsafe public static partial class maxmath /// The square root of 3. Approximately 1.73. public const float SQRT3 = 1.73205080f; + /// The square root of 5. Approximately 2.23. + public const float SQRT5 = 2.23606797f; + /// The cube root of 2. Approximately 1.26. public const float CBRT2 = 1.25992104f; diff --git a/Runtime/Math Lib/Functions/Arithmetic/Add-Subtract.cs b/Runtime/Math Lib/Functions/Arithmetic/Add-Subtract.cs index 729b9af..ba51f00 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Add-Subtract.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Add-Subtract.cs @@ -264,7 +264,7 @@ public static float2 addsub(float2 a, float2 b) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Xse.subadd_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); + return RegisterConversion.ToFloat2(Xse.subadd_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); } else { @@ -278,7 +278,7 @@ public static float3 addsub(float3 a, float3 b) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Xse.subadd_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); + return RegisterConversion.ToFloat3(Xse.subadd_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); } else { @@ -292,7 +292,7 @@ public static float4 addsub(float4 a, float4 b) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Xse.subadd_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); + return RegisterConversion.ToFloat4(Xse.subadd_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); } else { @@ -321,7 +321,7 @@ public static double2 addsub(double2 a, double2 b) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.subadd_pd(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); + return RegisterConversion.ToDouble2(Xse.subadd_pd(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); } else { @@ -335,7 +335,7 @@ public static double3 addsub(double3 a, double3 b) { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Xse.mm256_subadd_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b))); + return RegisterConversion.ToDouble3(Xse.mm256_subadd_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b))); } else { @@ -349,7 +349,7 @@ public static double4 addsub(double4 a, double4 b) { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Xse.mm256_subadd_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b))); + return RegisterConversion.ToDouble4(Xse.mm256_subadd_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b))); } else { @@ -599,7 +599,7 @@ public static uint2 addsub(uint2 a, uint2 b) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.subadd_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 2)); + return RegisterConversion.ToUInt2(Xse.subadd_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 2)); } else { @@ -613,7 +613,7 @@ public static uint3 addsub(uint3 a, uint3 b) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.subadd_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 3)); + return RegisterConversion.ToUInt3(Xse.subadd_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 3)); } else { @@ -627,7 +627,7 @@ public static uint4 addsub(uint4 a, uint4 b) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.subadd_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 4)); + return RegisterConversion.ToUInt4(Xse.subadd_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Average.cs b/Runtime/Math Lib/Functions/Arithmetic/Average.cs index f73b935..1d5ae6d 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Average.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Average.cs @@ -811,7 +811,7 @@ public static uint2 avg(uint2 x, uint2 y, Promise noOverflow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.avg_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), noOverflow.Promises(Promise.NoOverflow))); + return RegisterConversion.ToUInt2(Xse.avg_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), noOverflow.Promises(Promise.NoOverflow))); } else { @@ -833,7 +833,7 @@ public static uint3 avg(uint3 x, uint3 y, Promise noOverflow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.avg_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), noOverflow.Promises(Promise.NoOverflow))); + return RegisterConversion.ToUInt3(Xse.avg_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), noOverflow.Promises(Promise.NoOverflow))); } else { @@ -855,7 +855,7 @@ public static uint4 avg(uint4 x, uint4 y, Promise noOverflow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.avg_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), noOverflow.Promises(Promise.NoOverflow))); + return RegisterConversion.ToUInt4(Xse.avg_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), noOverflow.Promises(Promise.NoOverflow))); } else { @@ -902,7 +902,7 @@ public static int2 avg(int2 x, int2 y, Promise noOverflow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.avg_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), noOverflow.Promises(Promise.NoOverflow), 2)); + return RegisterConversion.ToInt2(Xse.avg_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), noOverflow.Promises(Promise.NoOverflow), 2)); } else { @@ -917,7 +917,7 @@ public static int3 avg(int3 x, int3 y, Promise noOverflow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.avg_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), noOverflow.Promises(Promise.NoOverflow), 3)); + return RegisterConversion.ToInt3(Xse.avg_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), noOverflow.Promises(Promise.NoOverflow), 3)); } else { @@ -932,7 +932,7 @@ public static int4 avg(int4 x, int4 y, Promise noOverflow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.avg_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), noOverflow.Promises(Promise.NoOverflow), 4)); + return RegisterConversion.ToInt4(Xse.avg_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), noOverflow.Promises(Promise.NoOverflow), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Divide With Remainder.cs b/Runtime/Math Lib/Functions/Arithmetic/Divide With Remainder.cs index 6c740c7..a593908 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Divide With Remainder.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Divide With Remainder.cs @@ -1192,8 +1192,8 @@ public static int2 divrem(int2 dividend, int2 divisor, out int2 remainder) { if (Sse2.IsSse2Supported) { - int2 ret = RegisterConversion.ToType(Xse.divrem_epi32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), out v128 rem, 2)); - remainder = RegisterConversion.ToType(rem); + int2 ret = RegisterConversion.ToInt2(Xse.divrem_epi32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), out v128 rem, 2)); + remainder = RegisterConversion.ToInt2(rem); return ret; } @@ -1211,8 +1211,8 @@ public static int3 divrem(int3 dividend, int3 divisor, out int3 remainder) { if (Sse2.IsSse2Supported) { - int3 ret = RegisterConversion.ToType(Xse.divrem_epi32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), out v128 rem, 3)); - remainder = RegisterConversion.ToType(rem); + int3 ret = RegisterConversion.ToInt3(Xse.divrem_epi32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), out v128 rem, 3)); + remainder = RegisterConversion.ToInt3(rem); return ret; } @@ -1230,8 +1230,8 @@ public static int4 divrem(int4 dividend, int4 divisor, out int4 remainder) { if (Sse2.IsSse2Supported) { - int4 ret = RegisterConversion.ToType(Xse.divrem_epi32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), out v128 rem, 4)); - remainder = RegisterConversion.ToType(rem); + int4 ret = RegisterConversion.ToInt4(Xse.divrem_epi32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), out v128 rem, 4)); + remainder = RegisterConversion.ToInt4(rem); return ret; } @@ -1280,8 +1280,8 @@ public static uint2 divrem(uint2 dividend, uint2 divisor, out uint2 remainder) { if (Sse2.IsSse2Supported) { - uint2 ret = RegisterConversion.ToType(Xse.divrem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), out v128 rem, 2)); - remainder = RegisterConversion.ToType(rem); + uint2 ret = RegisterConversion.ToUInt2(Xse.divrem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), out v128 rem, 2)); + remainder = RegisterConversion.ToUInt2(rem); return ret; } @@ -1299,8 +1299,8 @@ public static uint3 divrem(uint3 dividend, uint3 divisor, out uint3 remainder) { if (Sse2.IsSse2Supported) { - uint3 ret = RegisterConversion.ToType(Xse.divrem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), out v128 rem, 3)); - remainder = RegisterConversion.ToType(rem); + uint3 ret = RegisterConversion.ToUInt3(Xse.divrem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), out v128 rem, 3)); + remainder = RegisterConversion.ToUInt3(rem); return ret; } @@ -1318,8 +1318,8 @@ public static uint4 divrem(uint4 dividend, uint4 divisor, out uint4 remainder) { if (Sse2.IsSse2Supported) { - uint4 ret = RegisterConversion.ToType(Xse.divrem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), out v128 rem, 4)); - remainder = RegisterConversion.ToType(rem); + uint4 ret = RegisterConversion.ToUInt4(Xse.divrem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), out v128 rem, 4)); + remainder = RegisterConversion.ToUInt4(rem); return ret; } diff --git a/Runtime/Math Lib/Functions/Arithmetic/FMA/Float Divide-Add-Subtract.cs b/Runtime/Math Lib/Functions/Arithmetic/FMA/Float Divide-Add-Subtract.cs index 40668e6..152df69 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/FMA/Float Divide-Add-Subtract.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/FMA/Float Divide-Add-Subtract.cs @@ -15,7 +15,7 @@ public static float2 dadsub(float2 a, float2 b, float2 c, bool fast = false) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Xse.fmsubadd_ps(RegisterConversion.ToV128(a), + return RegisterConversion.ToFloat2(Xse.fmsubadd_ps(RegisterConversion.ToV128(a), fast ? Sse.rcp_ps(RegisterConversion.ToV128(b)) : RegisterConversion.ToV128(math.rcp(b)), RegisterConversion.ToV128(c))); } @@ -31,7 +31,7 @@ public static float3 dadsub(float3 a, float3 b, float3 c, bool fast = false) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Xse.fmsubadd_ps(RegisterConversion.ToV128(a), + return RegisterConversion.ToFloat3(Xse.fmsubadd_ps(RegisterConversion.ToV128(a), fast ? Sse.rcp_ps(RegisterConversion.ToV128(b)) : RegisterConversion.ToV128(math.rcp(b)), RegisterConversion.ToV128(c))); } @@ -47,7 +47,7 @@ public static float4 dadsub(float4 a, float4 b, float4 c, bool fast = false) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Xse.fmsubadd_ps(RegisterConversion.ToV128(a), + return RegisterConversion.ToFloat4(Xse.fmsubadd_ps(RegisterConversion.ToV128(a), fast ? Sse.rcp_ps(RegisterConversion.ToV128(b)) : RegisterConversion.ToV128(math.rcp(b)), RegisterConversion.ToV128(c))); } @@ -78,7 +78,7 @@ public static double2 dadsub(double2 a, double2 b, double2 c, bool fast = false) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.fmsubadd_pd(RegisterConversion.ToV128(a), + return RegisterConversion.ToDouble2(Xse.fmsubadd_pd(RegisterConversion.ToV128(a), fast ? Xse.rcp_pd(RegisterConversion.ToV128(b)) : RegisterConversion.ToV128(math.rcp(b)), RegisterConversion.ToV128(c))); } @@ -105,7 +105,7 @@ public static double3 dadsub(double3 a, double3 b, double3 c, bool fast = false) divisor = RegisterConversion.ToV256(math.rcp(b)); } - return RegisterConversion.ToType(Xse.mm256_fmsubadd_ps(RegisterConversion.ToV256(a), divisor, RegisterConversion.ToV256(c))); + return RegisterConversion.ToDouble3(Xse.mm256_fmsubadd_ps(RegisterConversion.ToV256(a), divisor, RegisterConversion.ToV256(c))); } else { @@ -130,7 +130,7 @@ public static double4 dadsub(double4 a, double4 b, double4 c, bool fast = false) divisor = RegisterConversion.ToV256(math.rcp(b)); } - return RegisterConversion.ToType(Xse.mm256_fmsubadd_ps(RegisterConversion.ToV256(a), divisor, RegisterConversion.ToV256(c))); + return RegisterConversion.ToDouble4(Xse.mm256_fmsubadd_ps(RegisterConversion.ToV256(a), divisor, RegisterConversion.ToV256(c))); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/FMA/Float Divide-Subtract-Add.cs.cs b/Runtime/Math Lib/Functions/Arithmetic/FMA/Float Divide-Subtract-Add.cs.cs index 3802eed..ca30808 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/FMA/Float Divide-Subtract-Add.cs.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/FMA/Float Divide-Subtract-Add.cs.cs @@ -15,7 +15,7 @@ public static float2 dsubadd(float2 a, float2 b, float2 c, bool fast = false) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Xse.fmaddsub_ps(RegisterConversion.ToV128(a), + return RegisterConversion.ToFloat2(Xse.fmaddsub_ps(RegisterConversion.ToV128(a), fast ? Sse.rcp_ps(RegisterConversion.ToV128(b)) : RegisterConversion.ToV128(math.rcp(b)), RegisterConversion.ToV128(c))); } @@ -31,7 +31,7 @@ public static float3 dsubadd(float3 a, float3 b, float3 c, bool fast = false) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Xse.fmaddsub_ps(RegisterConversion.ToV128(a), + return RegisterConversion.ToFloat3(Xse.fmaddsub_ps(RegisterConversion.ToV128(a), fast ? Sse.rcp_ps(RegisterConversion.ToV128(b)) : RegisterConversion.ToV128(math.rcp(b)), RegisterConversion.ToV128(c))); } @@ -47,7 +47,7 @@ public static float4 dsubadd(float4 a, float4 b, float4 c, bool fast = false) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Xse.fmaddsub_ps(RegisterConversion.ToV128(a), + return RegisterConversion.ToFloat4(Xse.fmaddsub_ps(RegisterConversion.ToV128(a), fast ? Sse.rcp_ps(RegisterConversion.ToV128(b)) : RegisterConversion.ToV128(math.rcp(b)), RegisterConversion.ToV128(c))); } @@ -78,7 +78,7 @@ public static double2 dsubadd(double2 a, double2 b, double2 c, bool fast = false { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.fmaddsub_pd(RegisterConversion.ToV128(a), + return RegisterConversion.ToDouble2(Xse.fmaddsub_pd(RegisterConversion.ToV128(a), fast ? Xse.rcp_pd(RegisterConversion.ToV128(b)) : RegisterConversion.ToV128(math.rcp(b)), RegisterConversion.ToV128(c))); } @@ -105,7 +105,7 @@ public static double3 dsubadd(double3 a, double3 b, double3 c, bool fast = false divisor = RegisterConversion.ToV256(math.rcp(b)); } - return RegisterConversion.ToType(Xse.mm256_fmaddsub_ps(RegisterConversion.ToV256(a), divisor, RegisterConversion.ToV256(c))); + return RegisterConversion.ToDouble3(Xse.mm256_fmaddsub_ps(RegisterConversion.ToV256(a), divisor, RegisterConversion.ToV256(c))); } else { @@ -130,7 +130,7 @@ public static double4 dsubadd(double4 a, double4 b, double4 c, bool fast = false divisor = RegisterConversion.ToV256(math.rcp(b)); } - return RegisterConversion.ToType(Xse.mm256_fmaddsub_ps(RegisterConversion.ToV256(a), divisor, RegisterConversion.ToV256(c))); + return RegisterConversion.ToDouble4(Xse.mm256_fmaddsub_ps(RegisterConversion.ToV256(a), divisor, RegisterConversion.ToV256(c))); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/FMA/Multiply-Add-Subtract.cs b/Runtime/Math Lib/Functions/Arithmetic/FMA/Multiply-Add-Subtract.cs index 3553674..20e5bf4 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/FMA/Multiply-Add-Subtract.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/FMA/Multiply-Add-Subtract.cs @@ -208,7 +208,7 @@ public static float2 madsub(float2 a, float2 b, float2 c) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.fmsubadd_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c))); + return RegisterConversion.ToFloat2(Xse.fmsubadd_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c))); } else { @@ -222,7 +222,7 @@ public static float3 madsub(float3 a, float3 b, float3 c) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.fmsubadd_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c))); + return RegisterConversion.ToFloat3(Xse.fmsubadd_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c))); } else { @@ -236,7 +236,7 @@ public static float4 madsub(float4 a, float4 b, float4 c) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.fmsubadd_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c))); + return RegisterConversion.ToFloat4(Xse.fmsubadd_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c))); } else { @@ -265,7 +265,7 @@ public static double2 madsub(double2 a, double2 b, double2 c) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.fmsubadd_pd(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c))); + return RegisterConversion.ToDouble2(Xse.fmsubadd_pd(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c))); } else { @@ -279,7 +279,7 @@ public static double3 madsub(double3 a, double3 b, double3 c) { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Xse.mm256_fmsubadd_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), RegisterConversion.ToV256(c))); + return RegisterConversion.ToDouble3(Xse.mm256_fmsubadd_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), RegisterConversion.ToV256(c))); } else { @@ -293,7 +293,7 @@ public static double4 madsub(double4 a, double4 b, double4 c) { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Xse.mm256_fmsubadd_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), RegisterConversion.ToV256(c))); + return RegisterConversion.ToDouble4(Xse.mm256_fmsubadd_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), RegisterConversion.ToV256(c))); } else { @@ -543,7 +543,7 @@ public static uint2 madsub(uint2 a, uint2 b, uint2 c) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.fmsubadd_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c), 2)); + return RegisterConversion.ToUInt2(Xse.fmsubadd_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c), 2)); } else { @@ -557,7 +557,7 @@ public static uint3 madsub(uint3 a, uint3 b, uint3 c) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.fmsubadd_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c), 3)); + return RegisterConversion.ToUInt3(Xse.fmsubadd_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c), 3)); } else { @@ -571,7 +571,7 @@ public static uint4 madsub(uint4 a, uint4 b, uint4 c) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.fmsubadd_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c), 4)); + return RegisterConversion.ToUInt4(Xse.fmsubadd_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/FMA/Multiply-Subtract-Add.cs.cs b/Runtime/Math Lib/Functions/Arithmetic/FMA/Multiply-Subtract-Add.cs.cs index f78045e..6a05893 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/FMA/Multiply-Subtract-Add.cs.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/FMA/Multiply-Subtract-Add.cs.cs @@ -208,7 +208,7 @@ public static float2 msubadd(float2 a, float2 b, float2 c) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.fmaddsub_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c))); + return RegisterConversion.ToFloat2(Xse.fmaddsub_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c))); } else { @@ -222,7 +222,7 @@ public static float3 msubadd(float3 a, float3 b, float3 c) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.fmaddsub_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c))); + return RegisterConversion.ToFloat3(Xse.fmaddsub_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c))); } else { @@ -236,7 +236,7 @@ public static float4 msubadd(float4 a, float4 b, float4 c) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.fmaddsub_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c))); + return RegisterConversion.ToFloat4(Xse.fmaddsub_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c))); } else { @@ -265,7 +265,7 @@ public static double2 msubadd(double2 a, double2 b, double2 c) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.fmaddsub_pd(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c))); + return RegisterConversion.ToDouble2(Xse.fmaddsub_pd(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c))); } else { @@ -279,7 +279,7 @@ public static double3 msubadd(double3 a, double3 b, double3 c) { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Xse.mm256_fmaddsub_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), RegisterConversion.ToV256(c))); + return RegisterConversion.ToDouble3(Xse.mm256_fmaddsub_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), RegisterConversion.ToV256(c))); } else { @@ -293,7 +293,7 @@ public static double4 msubadd(double4 a, double4 b, double4 c) { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Xse.mm256_fmaddsub_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), RegisterConversion.ToV256(c))); + return RegisterConversion.ToDouble4(Xse.mm256_fmaddsub_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), RegisterConversion.ToV256(c))); } else { @@ -543,7 +543,7 @@ public static uint2 msubadd(uint2 a, uint2 b, uint2 c) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.fmaddsub_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c), 2)); + return RegisterConversion.ToUInt2(Xse.fmaddsub_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c), 2)); } else { @@ -557,7 +557,7 @@ public static uint3 msubadd(uint3 a, uint3 b, uint3 c) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.fmaddsub_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c), 3)); + return RegisterConversion.ToUInt3(Xse.fmaddsub_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c), 3)); } else { @@ -571,7 +571,7 @@ public static uint4 msubadd(uint4 a, uint4 b, uint4 c) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.fmaddsub_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c), 4)); + return RegisterConversion.ToUInt4(Xse.fmaddsub_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), RegisterConversion.ToV128(c), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Floating Point/(Reciprocal) Cube Root.cs b/Runtime/Math Lib/Functions/Arithmetic/Floating Point/(Reciprocal) Cube Root.cs index fcc50fb..db97cf9 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Floating Point/(Reciprocal) Cube Root.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Floating Point/(Reciprocal) Cube Root.cs @@ -21,7 +21,10 @@ public static v128 cbrt_ps(v128 a, bool promise = false, byte elements = 4) { /*const*/ bool NEED_TO_SAVE_SIGN = !(promise || constexpr.ALL_LT_EPU32(a, 1u << 31, elements)); + v128 ONE = Sse.set1_ps(1f); + v128 ONE_THIRD = Sse.set1_ps(1f / 3f); v128 TWO_THIRDS = Sse.set1_ps(2f / 3f); + v128 absX = a; if (NEED_TO_SAVE_SIGN) @@ -35,11 +38,11 @@ public static v128 cbrt_ps(v128 a, bool promise = false, byte elements = 4) v128 c = Sse.mul_ps(Sse.mul_ps(absX, y), Sse.mul_ps(y, y)); y = Sse.mul_ps(y, fnmadd_ps(fnmadd_ps(Sse.set1_ps(F32_C2), c, Sse.set1_ps(F32_C1)), c, Sse.set1_ps(F32_C0))); v128 d = Sse.mul_ps(absX, y); - c = fnmadd_ps(d, Sse.mul_ps(y, y), Sse.set1_ps(1f)); + c = fnmadd_ps(d, Sse.mul_ps(y, y), ONE); - y = Sse.mul_ps(Sse.mul_ps(d, y), fmadd_ps(c, Sse.set1_ps(1f / 3f), Sse.set1_ps(1f))); + y = Sse.mul_ps(Sse.mul_ps(d, y), fmadd_ps(c, ONE_THIRD, ONE)); // additional NR - y = fdadd_ps(Sse.mul_ps(Sse.set1_ps(1f / 3f), a), Sse.mul_ps(y, y), Sse.mul_ps(TWO_THIRDS, y)); + y = fdadd_ps(Sse.mul_ps(ONE_THIRD, a), Sse.mul_ps(y, y), Sse.mul_ps(TWO_THIRDS, y)); // FloatPrecision.Low 2nd to last y (!!!save sign somehow!!!) // FloatPrecision.Medium+ last y @@ -56,7 +59,10 @@ public static v256 mm256_cbrt_ps(v256 a, bool promise = false) { /*const*/ bool NEED_TO_SAVE_SIGN = !(promise || constexpr.ALL_LT_EPU32(a, 1u << 31)); + v256 ONE = Avx.mm256_set1_ps(1f); + v256 ONE_THIRD = Avx.mm256_set1_ps(1f / 3f); v256 TWO_THIRDS = Avx.mm256_set1_ps(2f / 3f); + v256 absX = a; if (NEED_TO_SAVE_SIGN) @@ -82,11 +88,11 @@ public static v256 mm256_cbrt_ps(v256 a, bool promise = false) v256 c = Avx.mm256_mul_ps(Avx.mm256_mul_ps(absX, y), Avx.mm256_mul_ps(y, y)); y = Avx.mm256_mul_ps(y, mm256_fnmadd_ps(mm256_fnmadd_ps(Avx.mm256_set1_ps(F32_C2), c, Avx.mm256_set1_ps(F32_C1)), c, Avx.mm256_set1_ps(F32_C0))); v256 d = Avx.mm256_mul_ps(absX, y); - c = mm256_fnmadd_ps(d, Avx.mm256_mul_ps(y, y), Avx.mm256_set1_ps(1f)); + c = mm256_fnmadd_ps(d, Avx.mm256_mul_ps(y, y), ONE); - y = Avx.mm256_mul_ps(Avx.mm256_mul_ps(d, y), mm256_fmadd_ps(c, Avx.mm256_set1_ps(1f / 3f), Avx.mm256_set1_ps(1f))); + y = Avx.mm256_mul_ps(Avx.mm256_mul_ps(d, y), mm256_fmadd_ps(c, ONE_THIRD, ONE)); // additional NR - y = mm256_fdadd_ps(Avx.mm256_mul_ps(Avx.mm256_set1_ps(1f / 3f), a), Avx.mm256_mul_ps(y, y), Avx.mm256_mul_ps(TWO_THIRDS, y)); + y = mm256_fdadd_ps(Avx.mm256_mul_ps(ONE_THIRD, a), Avx.mm256_mul_ps(y, y), Avx.mm256_mul_ps(TWO_THIRDS, y)); // FloatPrecision.Low 2nd to last y (!!!save sign somehow!!!) // FloatPrecision.Medium+ last y @@ -130,7 +136,7 @@ public static v128 cbrt_pd(v128 a) v128 t = Sse2.and_si128(a, Sse2.set1_epi64x(1L << 63)); t = Sse2.or_si128(t, Sse2.slli_epi64(absHi, 32)); - r = Sse2.mul_pd(Sse2.mul_pd(t, t), Sse2.mul_pd(t, Sse2.div_pd(Sse2.set1_pd(1d), a))); + r = Sse2.mul_pd(Sse2.mul_pd(t, Sse2.mul_pd(t, t)), Sse2.div_pd(Sse2.set1_pd(1d), a)); t = Sse2.mul_pd(t, fmadd_pd(Sse2.mul_pd(Sse2.mul_pd(r, r), r), fmadd_pd(Sse2.set1_pd(F64_C4), r, Sse2.set1_pd(F64_C3)), fmadd_pd(fmadd_pd(Sse2.set1_pd(F64_C2), r, Sse2.set1_pd(F64_C1)), r, Sse2.set1_pd(F64_C0)))); t = Sse2.and_si128(Sse2.add_epi64(t, Sse2.set1_epi64x(0x8000_0000)), Sse2.set1_epi64x(unchecked((long)0xFFFF_FFFF_C000_0000ul))); @@ -166,7 +172,7 @@ public static v256 mm256_cbrt_pd(v256 a) v256 t = Avx2.mm256_and_si256(a, Avx.mm256_set1_epi64x(1L << 63)); t = Avx2.mm256_or_si256(t, Avx2.mm256_slli_epi64(absHi, 32)); - r = Avx.mm256_mul_pd(Avx.mm256_mul_pd(t, t), Avx.mm256_mul_pd(t, Avx.mm256_div_pd(Avx.mm256_set1_pd(1d), a))); + r = Avx.mm256_mul_pd(Avx.mm256_mul_pd(t, Avx.mm256_mul_pd(t, t)), Avx.mm256_div_pd(Avx.mm256_set1_pd(1d), a)); t = Avx.mm256_mul_pd(t, mm256_fmadd_pd(Avx.mm256_mul_pd(Avx.mm256_mul_pd(r, r), r), mm256_fmadd_pd(Avx.mm256_set1_pd(F64_C4), r, Avx.mm256_set1_pd(F64_C3)), mm256_fmadd_pd(mm256_fmadd_pd(Avx.mm256_set1_pd(F64_C2), r, Avx.mm256_set1_pd(F64_C1)), r, Avx.mm256_set1_pd(F64_C0)))); t = Avx2.mm256_and_si256(Avx2.mm256_add_epi64(t, Avx.mm256_set1_epi64x(0x8000_0000)), Avx.mm256_set1_epi64x(unchecked((long)0xFFFF_FFFF_C000_0000ul))); @@ -292,7 +298,7 @@ public static v128 rcbrt_pd(v128 a) v128 t = Sse2.and_si128(a, Sse2.set1_epi64x(1L << 63)); t = Sse2.or_si128(t, Sse2.slli_epi64(absHi, 32)); - r = Sse2.mul_pd(Sse2.mul_pd(t, t), Sse2.mul_pd(t, Sse2.div_pd(Sse2.set1_pd(1d), a))); + r = Sse2.mul_pd(Sse2.mul_pd(t, Sse2.mul_pd(t, t)), Sse2.div_pd(Sse2.set1_pd(1d), a)); t = Sse2.mul_pd(t, fmadd_pd(Sse2.mul_pd(Sse2.mul_pd(r, r), r), fmadd_pd(Sse2.set1_pd(F64_C4), r, Sse2.set1_pd(F64_C3)), fmadd_pd(fmadd_pd(Sse2.set1_pd(F64_C2), r, Sse2.set1_pd(F64_C1)), r, Sse2.set1_pd(F64_C0)))); t = Sse2.and_si128(Sse2.add_epi64(t, Sse2.set1_epi64x(0x8000_0000)), Sse2.set1_epi64x(unchecked((long)0xFFFF_FFFF_C000_0000ul))); @@ -330,7 +336,7 @@ public static v256 mm256_rcbrt_pd(v256 a) v256 t = Avx2.mm256_and_si256(a, Avx.mm256_set1_epi64x(1L << 63)); t = Avx2.mm256_or_si256(t, Avx2.mm256_slli_epi64(absHi, 32)); - r = Avx.mm256_mul_pd(Avx.mm256_mul_pd(t, t), Avx.mm256_mul_pd(t, Avx.mm256_div_pd(Avx.mm256_set1_pd(1d), a))); + r = Avx.mm256_mul_pd(Avx.mm256_mul_pd(t, Avx.mm256_mul_pd(t, t)), Avx.mm256_div_pd(Avx.mm256_set1_pd(1d), a)); t = Avx.mm256_mul_pd(t, mm256_fmadd_pd(Avx.mm256_mul_pd(Avx.mm256_mul_pd(r, r), r), mm256_fmadd_pd(Avx.mm256_set1_pd(F64_C4), r, Avx.mm256_set1_pd(F64_C3)), mm256_fmadd_pd(mm256_fmadd_pd(Avx.mm256_set1_pd(F64_C2), r, Avx.mm256_set1_pd(F64_C1)), r, Avx.mm256_set1_pd(F64_C0)))); t = Avx2.mm256_and_si256(Avx2.mm256_add_epi64(t, Avx.mm256_set1_epi64x(0x8000_0000)), Avx.mm256_set1_epi64x(unchecked((long)0xFFFF_FFFF_C000_0000ul))); @@ -397,7 +403,7 @@ public static float2 cbrt(float2 x, Promise positive = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cbrt_ps(RegisterConversion.ToV128(x), positive.Promises(Promise.Positive), 2)); + return RegisterConversion.ToFloat2(Xse.cbrt_ps(RegisterConversion.ToV128(x), positive.Promises(Promise.Positive), 2)); } else { @@ -412,7 +418,7 @@ public static float3 cbrt(float3 x, Promise positive = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cbrt_ps(RegisterConversion.ToV128(x), positive.Promises(Promise.Positive), 3)); + return RegisterConversion.ToFloat3(Xse.cbrt_ps(RegisterConversion.ToV128(x), positive.Promises(Promise.Positive), 3)); } else { @@ -427,7 +433,7 @@ public static float4 cbrt(float4 x, Promise positive = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cbrt_ps(RegisterConversion.ToV128(x), positive.Promises(Promise.Positive), 4)); + return RegisterConversion.ToFloat4(Xse.cbrt_ps(RegisterConversion.ToV128(x), positive.Promises(Promise.Positive), 4)); } else { @@ -479,7 +485,7 @@ public static double cbrt(double x) u |= (ulong)hi << 32; double t = *(double*)&u; - r = (t * t) * (t * (1d / x)); + r = (t * t * t) * (1d / x); t *= math.mad(r * r * r, math.mad(F64_C4, r, F64_C3), math.mad(math.mad(F64_C2, r, F64_C1), r, F64_C0)); u = (*(ulong*)&t + 0x8000_0000) & 0xFFFF_FFFF_C000_0000ul; t = *(double*)&u; @@ -497,7 +503,7 @@ public static double2 cbrt(double2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cbrt_pd(RegisterConversion.ToV128(x))); + return RegisterConversion.ToDouble2(Xse.cbrt_pd(RegisterConversion.ToV128(x))); } else { @@ -511,7 +517,7 @@ public static double3 cbrt(double3 x) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_cbrt_pd(RegisterConversion.ToV256(x))); + return RegisterConversion.ToDouble3(Xse.mm256_cbrt_pd(RegisterConversion.ToV256(x))); } else { @@ -525,7 +531,7 @@ public static double4 cbrt(double4 x) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_cbrt_pd(RegisterConversion.ToV256(x))); + return RegisterConversion.ToDouble4(Xse.mm256_cbrt_pd(RegisterConversion.ToV256(x))); } else { @@ -581,7 +587,7 @@ public static float2 rcbrt(float2 x, Promise positive = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.rcbrt_ps(RegisterConversion.ToV128(x), positive.Promises(Promise.Positive), 2)); + return RegisterConversion.ToFloat2(Xse.rcbrt_ps(RegisterConversion.ToV128(x), positive.Promises(Promise.Positive), 2)); } else { @@ -596,7 +602,7 @@ public static float3 rcbrt(float3 x, Promise positive = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.rcbrt_ps(RegisterConversion.ToV128(x), positive.Promises(Promise.Positive), 3)); + return RegisterConversion.ToFloat3(Xse.rcbrt_ps(RegisterConversion.ToV128(x), positive.Promises(Promise.Positive), 3)); } else { @@ -611,7 +617,7 @@ public static float4 rcbrt(float4 x, Promise positive = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.rcbrt_ps(RegisterConversion.ToV128(x), positive.Promises(Promise.Positive), 4)); + return RegisterConversion.ToFloat4(Xse.rcbrt_ps(RegisterConversion.ToV128(x), positive.Promises(Promise.Positive), 4)); } else { @@ -663,7 +669,7 @@ public static double rcbrt(double x) u |= (ulong)hi << 32; double t = *(double*)&u; - r = (t * t) * (t * (1d / x)); + r = (t * t * t) * (1d / x); t *= math.mad(r * r * r, math.mad(F64_C4, r, F64_C3), math.mad(math.mad(F64_C2, r, F64_C1), r, F64_C0)); u = (*(ulong*)&t + 0x8000_0000) & 0xFFFF_FFFF_C000_0000ul; t = *(double*)&u; @@ -682,7 +688,7 @@ public static double2 rcbrt(double2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.rcbrt_pd(RegisterConversion.ToV128(x))); + return RegisterConversion.ToDouble2(Xse.rcbrt_pd(RegisterConversion.ToV128(x))); } else { @@ -696,7 +702,7 @@ public static double3 rcbrt(double3 x) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_rcbrt_pd(RegisterConversion.ToV256(x))); + return RegisterConversion.ToDouble3(Xse.mm256_rcbrt_pd(RegisterConversion.ToV256(x))); } else { @@ -710,7 +716,7 @@ public static double4 rcbrt(double4 x) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_rcbrt_pd(RegisterConversion.ToV256(x))); + return RegisterConversion.ToDouble4(Xse.mm256_rcbrt_pd(RegisterConversion.ToV256(x))); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Floating Point/Fast Approximate Inverse Square Root.cs b/Runtime/Math Lib/Functions/Arithmetic/Floating Point/Fast Approximate Inverse Square Root.cs index 53cf02b..02f8913 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Floating Point/Fast Approximate Inverse Square Root.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Floating Point/Fast Approximate Inverse Square Root.cs @@ -28,7 +28,7 @@ public static float4 fastrsqrt(float4 x) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Sse.rsqrt_ps(RegisterConversion.ToV128(x))); + return RegisterConversion.ToFloat4(Sse.rsqrt_ps(RegisterConversion.ToV128(x))); } else { @@ -42,7 +42,7 @@ public static float3 fastrsqrt(float3 x) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Sse.rsqrt_ps(RegisterConversion.ToV128(x))); + return RegisterConversion.ToFloat3(Sse.rsqrt_ps(RegisterConversion.ToV128(x))); } else { @@ -56,7 +56,7 @@ public static float2 fastrsqrt(float2 x) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Sse.rsqrt_ps(RegisterConversion.ToV128(x))); + return RegisterConversion.ToFloat2(Sse.rsqrt_ps(RegisterConversion.ToV128(x))); } else { @@ -85,7 +85,7 @@ public static double4 fastrsqrt(double4 x) { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Xse.mm256_rsqrt_pd(RegisterConversion.ToV256(x))); + return RegisterConversion.ToDouble4(Xse.mm256_rsqrt_pd(RegisterConversion.ToV256(x))); } else { @@ -99,7 +99,7 @@ public static double3 fastrsqrt(double3 x) { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Xse.mm256_rsqrt_pd(RegisterConversion.ToV256(x))); + return RegisterConversion.ToDouble3(Xse.mm256_rsqrt_pd(RegisterConversion.ToV256(x))); } else { @@ -113,7 +113,7 @@ public static double2 fastrsqrt(double2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.rsqrt_pd(RegisterConversion.ToV128(x))); + return RegisterConversion.ToDouble2(Xse.rsqrt_pd(RegisterConversion.ToV128(x))); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Floating Point/Fast Approximate Reciprocal.cs b/Runtime/Math Lib/Functions/Arithmetic/Floating Point/Fast Approximate Reciprocal.cs index 2d988d3..85bed46 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Floating Point/Fast Approximate Reciprocal.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Floating Point/Fast Approximate Reciprocal.cs @@ -28,7 +28,7 @@ public static float4 fastrcp(float4 x) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Sse.rcp_ps(RegisterConversion.ToV128(x))); + return RegisterConversion.ToFloat4(Sse.rcp_ps(RegisterConversion.ToV128(x))); } else { @@ -42,7 +42,7 @@ public static float3 fastrcp(float3 x) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Sse.rcp_ps(RegisterConversion.ToV128(x))); + return RegisterConversion.ToFloat3(Sse.rcp_ps(RegisterConversion.ToV128(x))); } else { @@ -56,7 +56,7 @@ public static float2 fastrcp(float2 x) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Sse.rcp_ps(RegisterConversion.ToV128(x))); + return RegisterConversion.ToFloat2(Sse.rcp_ps(RegisterConversion.ToV128(x))); } else { @@ -85,7 +85,7 @@ public static double4 fastrcp(double4 x) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_rcp_pd(RegisterConversion.ToV256(x))); + return RegisterConversion.ToDouble4(Xse.mm256_rcp_pd(RegisterConversion.ToV256(x))); } else { @@ -99,7 +99,7 @@ public static double3 fastrcp(double3 x) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_rcp_pd(RegisterConversion.ToV256(x))); + return RegisterConversion.ToDouble3(Xse.mm256_rcp_pd(RegisterConversion.ToV256(x))); } else { @@ -113,7 +113,7 @@ public static double2 fastrcp(double2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.rcp_pd(RegisterConversion.ToV128(x))); + return RegisterConversion.ToDouble2(Xse.rcp_pd(RegisterConversion.ToV128(x))); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Floating Point/Logarithm Any Base.cs b/Runtime/Math Lib/Functions/Arithmetic/Floating Point/Logarithm Any Base.cs index 324de2c..b015233 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Floating Point/Logarithm Any Base.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Floating Point/Logarithm Any Base.cs @@ -74,7 +74,7 @@ public static float3 log(float3 x, float3 b) v128 _x = Avx.mm256_castps256_ps128(ln); v128 _b = Avx.mm256_extractf128_ps(ln, 1); - return RegisterConversion.ToType(Sse.div_ps(_x, _b)); + return RegisterConversion.ToFloat3(Sse.div_ps(_x, _b)); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Integer/Base-10 Logarithm.cs b/Runtime/Math Lib/Functions/Arithmetic/Integer/Base-10 Logarithm.cs index 2bf3320..99de3ee 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Integer/Base-10 Logarithm.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Integer/Base-10 Logarithm.cs @@ -124,6 +124,8 @@ public static v128 log10_epu16(v128 a, byte elements = 8) cmp = negmask_epi16(cmp_negated); cmp = Sse2.sub_epi16(cmp, Sse2.bsrli_si128(cmp_negated, 4 * sizeof(short))); cmp = Sse2.add_epi16(cmp, Sse2.bsrli_si128(cmp, 2 * sizeof(short))); + + constexpr.ASSUME_LE_EPU16(cmp, 4); return cmp; } @@ -150,7 +152,7 @@ public static v128 log10_epu16(v128 a, byte elements = 8) v128 _2 = Sse2.set1_epi16(999); v128 _3 = Sse2.set1_epi16(9_999); - result = neg_epi16(cmpgt_epu16(a, _0, elements)); + result = negmask_epi16(cmpgt_epu16(a, _0, elements)); result = Sse2.sub_epi16(result, cmpgt_epu16(a, _1, elements)); result = Sse2.sub_epi16(result, cmpgt_epu16(a, _2, elements)); result = Sse2.sub_epi16(result, cmpgt_epu16(a, _3, elements)); @@ -231,8 +233,6 @@ public static v128 log10_epi16(v128 a, byte elements = 8) result = Sse2.sub_epi16(result, Sse2.cmpgt_epi16(a, NINETY_NINE)); result = Sse2.sub_epi16(result, Sse2.cmpgt_epi16(a, _999)); result = Sse2.sub_epi16(result, Sse2.cmpgt_epi16(a, _9_999)); - - return result; } constexpr.ASSUME_LE_EPU16(result, 4); @@ -303,15 +303,15 @@ public static v128 log10_epu32(v128 a, byte elements = 4) v128 MASK_100000000 = Sse2.set1_epi32(100_000_000); v128 MASK_1000000000 = Sse2.set1_epi32(1_000_000_000); - v128 result_10 = Sse2.cmpeq_epi32(a, Sse4_1.max_epu32(a, MASK_10)); - v128 result_100 = Sse2.cmpeq_epi32(a, Sse4_1.max_epu32(a, MASK_100)); - v128 result_1000 = Sse2.cmpeq_epi32(a, Sse4_1.max_epu32(a, MASK_1000)); - v128 result_10000 = Sse2.cmpeq_epi32(a, Sse4_1.max_epu32(a, MASK_10000)); - v128 result_100000 = Sse2.cmpeq_epi32(a, Sse4_1.max_epu32(a, MASK_100000)); - v128 result_1000000 = Sse2.cmpeq_epi32(a, Sse4_1.max_epu32(a, MASK_1000000)); - v128 result_10000000 = Sse2.cmpeq_epi32(a, Sse4_1.max_epu32(a, MASK_10000000)); - v128 result_100000000 = Sse2.cmpeq_epi32(a, Sse4_1.max_epu32(a, MASK_100000000)); - v128 result_1000000000 = Sse2.cmpeq_epi32(a, Sse4_1.max_epu32(a, MASK_1000000000)); + v128 result_10 = cmpge_epu32(a, MASK_10); + v128 result_100 = cmpge_epu32(a, MASK_100); + v128 result_1000 = cmpge_epu32(a, MASK_1000); + v128 result_10000 = cmpge_epu32(a, MASK_10000); + v128 result_100000 = cmpge_epu32(a, MASK_100000); + v128 result_1000000 = cmpge_epu32(a, MASK_1000000); + v128 result_10000000 = cmpge_epu32(a, MASK_10000000); + v128 result_100000000 = cmpge_epu32(a, MASK_100000000); + v128 result_1000000000 = cmpge_epu32(a, MASK_1000000000); result_10 = Ssse3.abs_epi32(result_10); result_100 = Ssse3.abs_epi32(result_100); @@ -341,18 +341,18 @@ public static v128 log10_epu32(v128 a, byte elements = 4) v128 zzzz = Sse2.shuffle_epi32(a, Sse.SHUFFLE(2, 2, 2, 2)); v128 wwww = Sse2.shuffle_epi32(a, Sse.SHUFFLE(3, 3, 3, 3)); - v128 xResult = Xse.cmpgt_epu32(xxxx, MASK_SMALL); - v128 yResult = Xse.cmpgt_epu32(yyyy, MASK_SMALL); - v128 zResult = Xse.cmpgt_epu32(zzzz, MASK_SMALL); - v128 wResult = Xse.cmpgt_epu32(wwww, MASK_SMALL); - xResult = Xse.neg_epi32(xResult); - yResult = Xse.neg_epi32(yResult); - zResult = Xse.neg_epi32(zResult); - wResult = Xse.neg_epi32(wResult); - xResult = Sse2.sub_epi32(xResult, Xse.cmpgt_epu32(xxxx, MASK_LARGE)); - yResult = Sse2.sub_epi32(yResult, Xse.cmpgt_epu32(yyyy, MASK_LARGE)); - zResult = Sse2.sub_epi32(zResult, Xse.cmpgt_epu32(zzzz, MASK_LARGE)); - wResult = Sse2.sub_epi32(wResult, Xse.cmpgt_epu32(wwww, MASK_LARGE)); + v128 xResult = cmpgt_epu32(xxxx, MASK_SMALL); + v128 yResult = cmpgt_epu32(yyyy, MASK_SMALL); + v128 zResult = cmpgt_epu32(zzzz, MASK_SMALL); + v128 wResult = cmpgt_epu32(wwww, MASK_SMALL); + xResult = negmask_epi32(xResult); + yResult = negmask_epi32(yResult); + zResult = negmask_epi32(zResult); + wResult = negmask_epi32(wResult); + xResult = Sse2.sub_epi32(xResult, cmpgt_epu32(xxxx, MASK_LARGE)); + yResult = Sse2.sub_epi32(yResult, cmpgt_epu32(yyyy, MASK_LARGE)); + zResult = Sse2.sub_epi32(zResult, cmpgt_epu32(zzzz, MASK_LARGE)); + wResult = Sse2.sub_epi32(wResult, cmpgt_epu32(wwww, MASK_LARGE)); xResult = Sse2.add_epi32(xResult, Sse2.bsrli_si128(xResult, 2 * sizeof(uint))); yResult = Sse2.add_epi32(yResult, Sse2.bsrli_si128(yResult, 2 * sizeof(uint))); zResult = Sse2.add_epi32(zResult, Sse2.bsrli_si128(zResult, 2 * sizeof(uint))); @@ -362,7 +362,7 @@ public static v128 log10_epu32(v128 a, byte elements = 4) zResult = Sse2.add_epi32(zResult, Sse2.bsrli_si128(zResult, 1 * sizeof(uint))); wResult = Sse2.add_epi32(wResult, Sse2.bsrli_si128(wResult, 1 * sizeof(uint))); - v128 lastCMP = Sse2.cmpeq_epi32(Xse.max_epu32(a, LAST), a); + v128 lastCMP = cmpgt_epu32(a, LAST); v128 xy = Sse2.unpacklo_epi32(xResult, yResult); v128 zw = Sse2.unpacklo_epi32(zResult, wResult); @@ -383,18 +383,18 @@ public static v128 log10_epu32(v128 a, byte elements = 4) v256 _y = Avx2.mm256_broadcastd_epi32(Sse2.bsrli_si128(a, 1 * sizeof(uint))); v256 _z = Avx2.mm256_broadcastd_epi32(Sse2.bsrli_si128(a, 2 * sizeof(uint))); - v256 resultX = Xse.mm256_cmpge_epu32(_x, MASK); + v256 resultX = mm256_cmpge_epu32(_x, MASK); v128 hiX = Avx2.mm256_extracti128_si256(resultX, 1); - v256 resultY = Xse.mm256_cmpge_epu32(_y, MASK); + v256 resultY = mm256_cmpge_epu32(_y, MASK); v128 hiY = Avx2.mm256_extracti128_si256(resultY, 1); - v256 resultZ = Xse.mm256_cmpge_epu32(_z, MASK); + v256 resultZ = mm256_cmpge_epu32(_z, MASK); v128 hiZ = Avx2.mm256_extracti128_si256(resultZ, 1); v128 resultX128 = Ssse3.abs_epi32(Avx.mm256_castsi256_si128(resultX)); v128 resultY128 = Ssse3.abs_epi32(Avx.mm256_castsi256_si128(resultY)); v128 resultZ128 = Ssse3.abs_epi32(Avx.mm256_castsi256_si128(resultZ)); - v128 lastCMP = Sse2.cmpeq_epi32(Sse4_1.max_epu32(a, LAST), a); + v128 lastCMP = cmpge_epu32(a, LAST); resultX128 = Sse2.sub_epi32(resultX128, hiX); resultY128 = Sse2.sub_epi32(resultY128, hiY); @@ -423,15 +423,15 @@ public static v128 log10_epu32(v128 a, byte elements = 4) v128 MASK_LARGE = new v128(100_000, 1_000_000, 10_000_000, 100_000_000); v128 MASK_LAST = new v128(1_000_000_000); - v128 xResult = Sse2.cmpeq_epi32(xxxx, Sse4_1.max_epu32(xxxx, MASK_SMALL)); - v128 yResult = Sse2.cmpeq_epi32(yyyy, Sse4_1.max_epu32(yyyy, MASK_SMALL)); - v128 zResult = Sse2.cmpeq_epi32(zzzz, Sse4_1.max_epu32(zzzz, MASK_SMALL)); + v128 xResult = cmpge_epu32(xxxx, MASK_SMALL); + v128 yResult = cmpge_epu32(yyyy, MASK_SMALL); + v128 zResult = cmpge_epu32(zzzz, MASK_SMALL); xResult = Ssse3.abs_epi32(xResult); yResult = Ssse3.abs_epi32(yResult); zResult = Ssse3.abs_epi32(zResult); - xResult = Sse2.sub_epi32(xResult, Sse2.cmpeq_epi32(xxxx, Sse4_1.max_epu32(xxxx, MASK_LARGE))); - yResult = Sse2.sub_epi32(yResult, Sse2.cmpeq_epi32(yyyy, Sse4_1.max_epu32(yyyy, MASK_LARGE))); - zResult = Sse2.sub_epi32(zResult, Sse2.cmpeq_epi32(zzzz, Sse4_1.max_epu32(zzzz, MASK_LARGE))); + xResult = Sse2.sub_epi32(xResult, cmpge_epu32(xxxx, MASK_LARGE)); + yResult = Sse2.sub_epi32(yResult, cmpge_epu32(yyyy, MASK_LARGE)); + zResult = Sse2.sub_epi32(zResult, cmpge_epu32(zzzz, MASK_LARGE)); xResult = Sse2.add_epi32(xResult, Sse2.bsrli_si128(xResult, 2 * sizeof(uint))); yResult = Sse2.add_epi32(yResult, Sse2.bsrli_si128(yResult, 2 * sizeof(uint))); zResult = Sse2.add_epi32(zResult, Sse2.bsrli_si128(zResult, 2 * sizeof(uint))); @@ -439,7 +439,7 @@ public static v128 log10_epu32(v128 a, byte elements = 4) yResult = Sse2.add_epi32(yResult, Sse2.bsrli_si128(yResult, 1 * sizeof(uint))); zResult = Sse2.add_epi32(zResult, Sse2.bsrli_si128(zResult, 1 * sizeof(uint))); - v128 lastCMP = Xse.cmpgt_epu32(a, MASK_LAST); + v128 lastCMP = cmpgt_epu32(a, MASK_LAST); v128 xy = Sse2.unpacklo_epi32(xResult, yResult); result = Sse2.unpacklo_epi64(xy, zResult); @@ -451,16 +451,16 @@ public static v128 log10_epu32(v128 a, byte elements = 4) v128 MASK_LARGE = new v128(99_999, 999_999, 9_999_999, 99_999_999); v128 MASK_LAST = new v128(999_999_999); - v128 xResult = Xse.cmpgt_epu32(xxxx, MASK_SMALL); - v128 yResult = Xse.cmpgt_epu32(yyyy, MASK_SMALL); - v128 zResult = Xse.cmpgt_epu32(zzzz, MASK_SMALL); + v128 xResult = cmpgt_epu32(xxxx, MASK_SMALL); + v128 yResult = cmpgt_epu32(yyyy, MASK_SMALL); + v128 zResult = cmpgt_epu32(zzzz, MASK_SMALL); - xResult = Xse.neg_epi32(xResult); - yResult = Xse.neg_epi32(yResult); - zResult = Xse.neg_epi32(zResult); - xResult = Sse2.sub_epi32(xResult, Xse.cmpgt_epu32(xxxx, MASK_LARGE)); - yResult = Sse2.sub_epi32(yResult, Xse.cmpgt_epu32(yyyy, MASK_LARGE)); - zResult = Sse2.sub_epi32(zResult, Xse.cmpgt_epu32(zzzz, MASK_LARGE)); + xResult = negmask_epi32(xResult); + yResult = negmask_epi32(yResult); + zResult = negmask_epi32(zResult); + xResult = Sse2.sub_epi32(xResult, cmpgt_epu32(xxxx, MASK_LARGE)); + yResult = Sse2.sub_epi32(yResult, cmpgt_epu32(yyyy, MASK_LARGE)); + zResult = Sse2.sub_epi32(zResult, cmpgt_epu32(zzzz, MASK_LARGE)); xResult = Sse2.add_epi32(xResult, Sse2.bsrli_si128(xResult, 2 * sizeof(uint))); yResult = Sse2.add_epi32(yResult, Sse2.bsrli_si128(yResult, 2 * sizeof(uint))); zResult = Sse2.add_epi32(zResult, Sse2.bsrli_si128(zResult, 2 * sizeof(uint))); @@ -468,7 +468,7 @@ public static v128 log10_epu32(v128 a, byte elements = 4) yResult = Sse2.add_epi32(yResult, Sse2.bsrli_si128(yResult, 1 * sizeof(uint))); zResult = Sse2.add_epi32(zResult, Sse2.bsrli_si128(zResult, 1 * sizeof(uint))); - v128 lastCMP = Xse.cmpgt_epu32(a, MASK_LAST); + v128 lastCMP = cmpgt_epu32(a, MASK_LAST); v128 xy = Sse2.unpacklo_epi32(xResult, yResult); result = Sse2.unpacklo_epi64(xy, zResult); @@ -488,15 +488,15 @@ public static v128 log10_epu32(v128 a, byte elements = 4) v256 _x = Avx2.mm256_broadcastd_epi32(a); v256 _y = Avx2.mm256_broadcastd_epi32(Sse2.bsrli_si128(a, 1 * sizeof(uint))); - v256 resultX = Xse.mm256_cmpge_epu32(_x, MASK); + v256 resultX = mm256_cmpge_epu32(_x, MASK); v128 hiX = Avx2.mm256_extracti128_si256(resultX, 1); - v256 resultY = Xse.mm256_cmpge_epu32(_y, MASK); + v256 resultY = mm256_cmpge_epu32(_y, MASK); v128 hiY = Avx2.mm256_extracti128_si256(resultY, 1); v128 resultX128 = Ssse3.abs_epi32(Avx.mm256_castsi256_si128(resultX)); v128 resultY128 = Ssse3.abs_epi32(Avx.mm256_castsi256_si128(resultY)); - v128 lastCMP = Sse2.cmpeq_epi32(Sse4_1.max_epu32(a, LAST), a); + v128 lastCMP = cmpge_epu32(a, LAST); resultX128 = Sse2.sub_epi32(resultX128, hiX); resultY128 = Sse2.sub_epi32(resultY128, hiY); @@ -520,18 +520,18 @@ public static v128 log10_epu32(v128 a, byte elements = 4) v128 MASK_LARGE = new v128(100_000, 1_000_000, 10_000_000, 100_000_000); v128 MASK_LAST = Sse2.cvtsi64x_si128((1_000_000_000L << 32) | 1_000_000_000L); - v128 xResult = Sse2.cmpeq_epi32(xxxx, Sse4_1.max_epu32(xxxx, MASK_SMALL)); - v128 yResult = Sse2.cmpeq_epi32(yyyy, Sse4_1.max_epu32(yyyy, MASK_SMALL)); + v128 xResult = cmpge_epu32(xxxx, MASK_SMALL); + v128 yResult = cmpge_epu32(yyyy, MASK_SMALL); xResult = Ssse3.abs_epi32(xResult); yResult = Ssse3.abs_epi32(yResult); - xResult = Sse2.sub_epi32(xResult, Sse2.cmpeq_epi32(xxxx, Sse4_1.max_epu32(xxxx, MASK_LARGE))); - yResult = Sse2.sub_epi32(yResult, Sse2.cmpeq_epi32(yyyy, Sse4_1.max_epu32(yyyy, MASK_LARGE))); + xResult = Sse2.sub_epi32(xResult, cmpge_epu32(xxxx, MASK_LARGE)); + yResult = Sse2.sub_epi32(yResult, cmpge_epu32(yyyy, MASK_LARGE)); xResult = Sse2.add_epi32(xResult, Sse2.bsrli_si128(xResult, 2 * sizeof(uint))); yResult = Sse2.add_epi32(yResult, Sse2.bsrli_si128(yResult, 2 * sizeof(uint))); xResult = Sse2.add_epi32(xResult, Sse2.bsrli_si128(xResult, 1 * sizeof(uint))); yResult = Sse2.add_epi32(yResult, Sse2.bsrli_si128(yResult, 1 * sizeof(uint))); - v128 lastCMP = Sse2.cmpeq_epi32(a, Sse4_1.max_epu32(a, MASK_LAST)); + v128 lastCMP = cmpge_epu32(a, MASK_LAST); v128 xy = Sse2.unpacklo_epi32(xResult, yResult); result = Sse2.sub_epi32(xy, lastCMP); @@ -542,18 +542,18 @@ public static v128 log10_epu32(v128 a, byte elements = 4) v128 MASK_LARGE = new v128(99_999, 999_999, 9_999_999, 99_999_999); v128 MASK_LAST = Sse2.cvtsi64x_si128((999_999_999L << 32) | 999_999_999L); - v128 xResult = Xse.cmpgt_epu32(xxxx, MASK_SMALL); - v128 yResult = Xse.cmpgt_epu32(yyyy, MASK_SMALL); - xResult = Xse.neg_epi32(xResult); - yResult = Xse.neg_epi32(yResult); - xResult = Sse2.sub_epi32(xResult, Xse.cmpgt_epu32(xxxx, MASK_LARGE)); - yResult = Sse2.sub_epi32(yResult, Xse.cmpgt_epu32(yyyy, MASK_LARGE)); + v128 xResult = cmpgt_epu32(xxxx, MASK_SMALL); + v128 yResult = cmpgt_epu32(yyyy, MASK_SMALL); + xResult = negmask_epi32(xResult); + yResult = negmask_epi32(yResult); + xResult = Sse2.sub_epi32(xResult, cmpgt_epu32(xxxx, MASK_LARGE)); + yResult = Sse2.sub_epi32(yResult, cmpgt_epu32(yyyy, MASK_LARGE)); xResult = Sse2.add_epi32(xResult, Sse2.bsrli_si128(xResult, 2 * sizeof(uint))); yResult = Sse2.add_epi32(yResult, Sse2.bsrli_si128(yResult, 2 * sizeof(uint))); xResult = Sse2.add_epi32(xResult, Sse2.bsrli_si128(xResult, 1 * sizeof(uint))); yResult = Sse2.add_epi32(yResult, Sse2.bsrli_si128(yResult, 1 * sizeof(uint))); - v128 lastCMP = Xse.cmpgt_epu32(a, MASK_LAST); + v128 lastCMP = cmpgt_epu32(a, MASK_LAST); v128 xy = Sse2.unpacklo_epi32(xResult, yResult); result = Sse2.sub_epi32(xy, lastCMP); @@ -594,15 +594,15 @@ public static v256 mm256_log10_epu32(v256 a) v256 MASK_100000000 = Avx.mm256_set1_epi32(100_000_000); v256 MASK_1000000000 = Avx.mm256_set1_epi32(1_000_000_000); - v256 result_10 = Avx2.mm256_cmpeq_epi32(a, Avx2.mm256_max_epu32(a, MASK_10)); - v256 result_100 = Avx2.mm256_cmpeq_epi32(a, Avx2.mm256_max_epu32(a, MASK_100)); - v256 result_1000 = Avx2.mm256_cmpeq_epi32(a, Avx2.mm256_max_epu32(a, MASK_1000)); - v256 result_10000 = Avx2.mm256_cmpeq_epi32(a, Avx2.mm256_max_epu32(a, MASK_10000)); - v256 result_100000 = Avx2.mm256_cmpeq_epi32(a, Avx2.mm256_max_epu32(a, MASK_100000)); - v256 result_1000000 = Avx2.mm256_cmpeq_epi32(a, Avx2.mm256_max_epu32(a, MASK_1000000)); - v256 result_10000000 = Avx2.mm256_cmpeq_epi32(a, Avx2.mm256_max_epu32(a, MASK_10000000)); - v256 result_100000000 = Avx2.mm256_cmpeq_epi32(a, Avx2.mm256_max_epu32(a, MASK_100000000)); - v256 result_1000000000 = Avx2.mm256_cmpeq_epi32(a, Avx2.mm256_max_epu32(a, MASK_1000000000)); + v256 result_10 = mm256_cmpge_epu32(a, MASK_10); + v256 result_100 = mm256_cmpge_epu32(a, MASK_100); + v256 result_1000 = mm256_cmpge_epu32(a, MASK_1000); + v256 result_10000 = mm256_cmpge_epu32(a, MASK_10000); + v256 result_100000 = mm256_cmpge_epu32(a, MASK_100000); + v256 result_1000000 = mm256_cmpge_epu32(a, MASK_1000000); + v256 result_10000000 = mm256_cmpge_epu32(a, MASK_10000000); + v256 result_100000000 = mm256_cmpge_epu32(a, MASK_100000000); + v256 result_1000000000 = mm256_cmpge_epu32(a, MASK_1000000000); result_10 = Avx2.mm256_abs_epi32(result_10); result_100 = Avx2.mm256_abs_epi32(result_100); @@ -619,7 +619,11 @@ public static v256 mm256_log10_epu32(v256 a) result_100 = Avx2.mm256_add_epi32(result_100, result_1000); result_1000 = Avx2.mm256_add_epi32(result_10000, result_10); - return Avx2.mm256_add_epi32(result_100, result_1000); + v256 result = Avx2.mm256_add_epi32(result_100, result_1000); + + constexpr.ASSUME_LE_EPU32(result, 9); + + return result; } } else throw new IllegalInstructionException(); @@ -873,7 +877,11 @@ public static v256 mm256_log10_epi32(v256 a) result_99 = Avx2.mm256_add_epi32(result_99, result_999); result_999 = Avx2.mm256_add_epi32(result_9999, result_9); - return Avx2.mm256_add_epi32(result_99, result_999); + v256 result = Avx2.mm256_add_epi32(result_99, result_999); + + constexpr.ASSUME_LE_EPU32(result, 9); + + return result; } } else throw new IllegalInstructionException(); @@ -965,7 +973,11 @@ public static v128 log10_epu64(v128 a) UInt128 adjust0 = guess[math.lzcnt(a.ULong0)]; UInt128 adjust1 = guess[math.lzcnt(a.ULong1)]; - return new v128((adjust0 + a.ULong0).hi64, (adjust1 + a.ULong1).hi64); + v128 result = new v128((adjust0 + a.ULong0).hi64, (adjust1 + a.ULong1).hi64); + + constexpr.ASSUME_LE_EPU64(result, 19); + + return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1062,7 +1074,11 @@ public static v256 mm256_log10_epu64(v256 a, byte elements = 4) hi = Sse2.unpacklo_epi64(hi, Sse2.cvtsi64x_si128((long)((adjust3 + a.ULong3).hi64))); } - return new v256(lo, hi); + v256 result = new v256(lo, hi); + + constexpr.ASSUME_LE_EPU64(result, 19); + + return result; } } else throw new IllegalInstructionException(); @@ -1638,7 +1654,7 @@ public static uint2 intlog10(uint2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.log10_epu32(RegisterConversion.ToV128(x), 2)); + return RegisterConversion.ToUInt2(Xse.log10_epu32(RegisterConversion.ToV128(x), 2)); } else { @@ -1671,7 +1687,7 @@ public static uint3 intlog10(uint3 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.log10_epu32(RegisterConversion.ToV128(x), 3)); + return RegisterConversion.ToUInt3(Xse.log10_epu32(RegisterConversion.ToV128(x), 3)); } else { @@ -1706,7 +1722,7 @@ public static uint4 intlog10(uint4 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.log10_epu32(RegisterConversion.ToV128(x), 4)); + return RegisterConversion.ToUInt4(Xse.log10_epu32(RegisterConversion.ToV128(x), 4)); } else { @@ -1824,7 +1840,7 @@ public static int2 intlog10(int2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.log10_epi32(RegisterConversion.ToV128(x), 2)); + return RegisterConversion.ToInt2(Xse.log10_epi32(RegisterConversion.ToV128(x), 2)); } else { @@ -1839,7 +1855,7 @@ public static int3 intlog10(int3 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.log10_epi32(RegisterConversion.ToV128(x), 3)); + return RegisterConversion.ToInt3(Xse.log10_epi32(RegisterConversion.ToV128(x), 3)); } else { @@ -1854,7 +1870,7 @@ public static int4 intlog10(int4 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.log10_epi32(RegisterConversion.ToV128(x), 4)); + return RegisterConversion.ToInt4(Xse.log10_epi32(RegisterConversion.ToV128(x), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Integer/Binomial Coefficient.cs b/Runtime/Math Lib/Functions/Arithmetic/Integer/Binomial Coefficient.cs new file mode 100644 index 0000000..52a9484 --- /dev/null +++ b/Runtime/Math Lib/Functions/Arithmetic/Integer/Binomial Coefficient.cs @@ -0,0 +1,2878 @@ +using System.Runtime.CompilerServices; +using Unity.Burst.Intrinsics; +using Unity.Burst.CompilerServices; +using Unity.Mathematics; +using MaxMath.Intrinsics; +using DevTools; + +using static Unity.Burst.Intrinsics.X86; +using static MaxMath.LUT.FACTORIAL; + +namespace MaxMath +{ + namespace Intrinsics + { + unsafe public static partial class Xse + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v128 naivecomb_epu8(v128 n, v128 k, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + v128 nom = gamma_epu8(n, true, elements); + v128 denom = mullo_epi8(gamma_epu8(k, true, elements), gamma_epu8(Sse2.sub_epi8(n, k), true, elements), elements); + + return div_epu8(nom, denom, elements); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v256 mm256_naivecomb_epu8(v256 n, v256 k) + { + if (Avx2.IsAvx2Supported) + { + v256 nom = mm256_gamma_epu8(n, true); + v256 denom = mm256_mullo_epi8(mm256_gamma_epu8(k, true), mm256_gamma_epu8(Avx2.mm256_sub_epi8(n, k), true)); + + return mm256_div_epu8(nom, denom); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v128 naivecomb_epu16(v128 n, v128 k, bool epu8range = false, byte elements = 8) + { + v128 nom; + v128 denom; + if (Sse2.IsSse2Supported) + { + if (epu8range || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U8, elements)) + { + if (Ssse3.IsSsse3Supported) + { + nom = gamma_epu16_epu8range(n); + denom = Sse2.mullo_epi16(gamma_epu16_epu8range(k), gamma_epu16_epu8range(Sse2.sub_epi16(n, k))); + + return div_epu16(nom, denom, elements); + } + } + + nom = gamma_epu16(n, true, elements); + denom = Sse2.mullo_epi16(gamma_epu16(k, true, elements), gamma_epu16(Sse2.sub_epi16(n, k), true, elements)); + + return div_epu16(nom, denom, elements); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v256 mm256_naivecomb_epu16(v256 n, v256 k, bool epu8range = false) + { + if (Avx2.IsAvx2Supported) + { + if (epu8range || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U8)) + { + v256 nom = mm256_gamma_epu16_epu8range(n); + v256 denom = Avx2.mm256_mullo_epi16(mm256_gamma_epu16_epu8range(k), mm256_gamma_epu16_epu8range(Avx2.mm256_sub_epi16(n, k))); + + return mm256_div_epu16(nom, denom); + } + else + { + v256 nom = mm256_gamma_epu16(n, true); + v256 denom = Avx2.mm256_mullo_epi16(mm256_gamma_epu16(k, true), mm256_gamma_epu16(Avx2.mm256_sub_epi16(n, k), true)); + + return mm256_div_epu16(nom, denom); + } + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v128 naivecomb_epu32(v128 n, v128 k, byte elements = 4) + { + if (Sse2.IsSse2Supported) + { + v128 nom = gamma_epu32(n, true, elements); + v128 denom = mullo_epi32(gamma_epu32(k, true, elements), gamma_epu32(Sse2.sub_epi32(n, k), true, elements)); + + return div_epu32(nom, denom, elements); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v256 mm256_naivecomb_epu32(v256 n, v256 k) + { + if (Avx2.IsAvx2Supported) + { + v256 nom = mm256_gamma_epu32(n, true); + v256 denom = Avx2.mm256_mullo_epi32(mm256_gamma_epu32(k, true), mm256_gamma_epu32(Avx2.mm256_sub_epi32(n, k), true)); + + return mm256_div_epu32(nom, denom); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v128 naivecomb_epu64(v128 n, v128 k) + { + if (Sse2.IsSse2Supported) + { + v128 nom = gamma_epu64(n, true); + v128 denom = mullo_epi64(gamma_epu64(k, true), gamma_epu64(Sse2.sub_epi64(n, k), true)); + + return div_epu64(nom, denom); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v256 mm256_naivecomb_epu64(v256 n, v256 k, byte elements = 4) + { + if (Avx2.IsAvx2Supported) + { + v256 nom = mm256_gamma_epu64(n, true, elements); + v256 denom = mm256_mullo_epi64(mm256_gamma_epu64(k, true), mm256_gamma_epu64(Avx2.mm256_sub_epi64(n, k), true, elements)); + + return mm256_div_epu64(nom, denom, elements); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 comb_epu8(v128 n, v128 k, byte unsafeLevels = 0, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { +Assert.IsNotGreater(k.Byte0, n.Byte0); +Assert.IsNotGreater(k.Byte1, n.Byte1); +if (elements > 2) +{ +Assert.IsNotGreater(k.Byte2, n.Byte2); +} +if (elements > 3) +{ +Assert.IsNotGreater(k.Byte3, n.Byte3); +} +if (elements > 4) +{ +Assert.IsNotGreater(k.Byte4, n.Byte4); +Assert.IsNotGreater(k.Byte5, n.Byte5); +Assert.IsNotGreater(k.Byte6, n.Byte6); +Assert.IsNotGreater(k.Byte7, n.Byte7); +} +if (elements > 8) +{ +Assert.IsNotGreater(k.Byte8, n.Byte8); +Assert.IsNotGreater(k.Byte9, n.Byte9); +Assert.IsNotGreater(k.Byte10, n.Byte10); +Assert.IsNotGreater(k.Byte11, n.Byte11); +Assert.IsNotGreater(k.Byte12, n.Byte12); +Assert.IsNotGreater(k.Byte13, n.Byte13); +Assert.IsNotGreater(k.Byte14, n.Byte14); +Assert.IsNotGreater(k.Byte15, n.Byte15); +} + + if (unsafeLevels != 0 || constexpr.ALL_LE_EPU8(n, (byte)sbyte.MaxValue, elements)) + { + return comb_epi8(n, k, unsafeLevels, elements); + } + else + { + if (elements <= 8) + { + return cvtepi16_epi8(comb_epi16(cvtepu8_epi16(n), cvtepu8_epi16(k), elements: elements), elements); + } + else + { + if (Avx2.IsAvx2Supported) + { + return mm256_cvtepi16_epi8(mm256_comb_epi16(Avx2.mm256_cvtepu8_epi16(n), Avx2.mm256_cvtepu8_epi16(k))); + } + else + { + v128 ONE = Sse2.set1_epi8(1); + + k = Sse2.min_epu8(k, Sse2.sub_epi8(n, k)); + + v128 n2 = n; + n = Sse2.sub_epi8(n, ONE); + v128 c = Sse2.add_epi8(mullo_epi8(srli_epi8(n2, 1), n, 16), Sse2.and_si128(neg_epi8(Sse2.and_si128(n2, ONE)), srli_epi8(n, 1))); + v128 results = blendv_si128(blendv_si128(c, n2, Sse2.cmpeq_epi8(k, ONE)), ONE, Sse2.cmpeq_epi8(k, Sse2.setzero_si128())); + v128 i = Sse2.add_epi8(ONE, ONE); + v128 cmp = cmple_epu8(k, i); + + while (Hint.Likely(notalltrue_epi128(cmp, 16))) + { + i = Sse2.add_epi8(i, ONE); + v128 q = divrem_epu8(c, i, out v128 r); + n = Sse2.sub_epi8(n, ONE); + c = Sse2.add_epi8(mullo_epi8(q, n, 16), div_epu8(mullo_epi8(r, n, 16), i)); + + results = blendv_si128(c, results, cmp); + cmp = cmple_epu8(k, i); + } + + return results; + } + } + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_comb_epu8(v256 n, v256 k, byte unsafeLevels = 0) + { + if (Avx2.IsAvx2Supported) + { +Assert.IsNotGreater(k.Byte0, n.Byte0); +Assert.IsNotGreater(k.Byte1, n.Byte1); +Assert.IsNotGreater(k.Byte2, n.Byte2); +Assert.IsNotGreater(k.Byte3, n.Byte3); +Assert.IsNotGreater(k.Byte4, n.Byte4); +Assert.IsNotGreater(k.Byte5, n.Byte5); +Assert.IsNotGreater(k.Byte6, n.Byte6); +Assert.IsNotGreater(k.Byte7, n.Byte7); +Assert.IsNotGreater(k.Byte8, n.Byte8); +Assert.IsNotGreater(k.Byte9, n.Byte9); +Assert.IsNotGreater(k.Byte10, n.Byte10); +Assert.IsNotGreater(k.Byte11, n.Byte11); +Assert.IsNotGreater(k.Byte12, n.Byte12); +Assert.IsNotGreater(k.Byte13, n.Byte13); +Assert.IsNotGreater(k.Byte14, n.Byte14); +Assert.IsNotGreater(k.Byte15, n.Byte15); +Assert.IsNotGreater(k.Byte16, n.Byte16); +Assert.IsNotGreater(k.Byte17, n.Byte17); +Assert.IsNotGreater(k.Byte18, n.Byte18); +Assert.IsNotGreater(k.Byte19, n.Byte19); +Assert.IsNotGreater(k.Byte20, n.Byte20); +Assert.IsNotGreater(k.Byte21, n.Byte21); +Assert.IsNotGreater(k.Byte22, n.Byte22); +Assert.IsNotGreater(k.Byte23, n.Byte23); +Assert.IsNotGreater(k.Byte24, n.Byte24); +Assert.IsNotGreater(k.Byte25, n.Byte25); +Assert.IsNotGreater(k.Byte26, n.Byte26); +Assert.IsNotGreater(k.Byte27, n.Byte27); +Assert.IsNotGreater(k.Byte28, n.Byte28); +Assert.IsNotGreater(k.Byte29, n.Byte29); +Assert.IsNotGreater(k.Byte30, n.Byte30); +Assert.IsNotGreater(k.Byte31, n.Byte31); + + if (unsafeLevels != 0 || constexpr.ALL_LE_EPU8(n, (byte)sbyte.MaxValue)) + { + return mm256_comb_epi8(n, k, unsafeLevels); + } + else + { + v256 ONE = Avx.mm256_set1_epi8(1); + + k = Avx2.mm256_min_epu8(k, Avx2.mm256_sub_epi8(n, k)); + + v256 n2 = n; + n = Avx2.mm256_sub_epi8(n, ONE); + v256 c = Avx2.mm256_add_epi8(mm256_mullo_epi8(mm256_srli_epi8(n2, 1), n), Avx2.mm256_and_si256(mm256_neg_epi8(Avx2.mm256_and_si256(n2, ONE)), mm256_srli_epi8(n, 1))); + v256 results = mm256_blendv_si256(mm256_blendv_si256(c, n2, Avx2.mm256_cmpeq_epi8(k, ONE)), ONE, Avx2.mm256_cmpeq_epi8(k, Avx.mm256_setzero_si256())); + v256 i = Avx2.mm256_add_epi8(ONE, ONE); + v256 cmp = mm256_cmple_epu8(k, i); + + while (Hint.Likely(mm256_notalltrue_epi256(cmp, 32))) + { + i = Avx2.mm256_add_epi8(i, ONE); + v256 q = mm256_divrem_epu8(c, i, out v256 r); + n = Avx2.mm256_sub_epi8(n, ONE); + c = Avx2.mm256_add_epi8(mm256_mullo_epi8(q, n), mm256_div_epu8(mm256_mullo_epi8(r, n), i)); + + results = mm256_blendv_si256(c, results, cmp); + cmp = mm256_cmple_epu8(k, i); + } + + return results; + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 comb_epi8(v128 n, v128 k, byte unsafeLevels = 0, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { +Assert.IsNotGreater(k.SByte0, n.SByte0); +Assert.IsNotGreater(k.SByte1, n.SByte1); +Assert.IsNonNegative(k.SByte0); +Assert.IsNonNegative(n.SByte0); +Assert.IsNonNegative(k.SByte1); +Assert.IsNonNegative(n.SByte1); +if (elements > 2) +{ +Assert.IsNotGreater(k.SByte2, n.SByte2); +Assert.IsNonNegative(k.SByte2); +Assert.IsNonNegative(n.SByte2); +} +if (elements > 3) +{ +Assert.IsNotGreater(k.SByte3, n.SByte3); +Assert.IsNonNegative(k.SByte3); +Assert.IsNonNegative(n.SByte3); +} +if (elements > 4) +{ +Assert.IsNotGreater(k.SByte4, n.SByte4); +Assert.IsNotGreater(k.SByte5, n.SByte5); +Assert.IsNotGreater(k.SByte6, n.SByte6); +Assert.IsNotGreater(k.SByte7, n.SByte7); +Assert.IsNonNegative(k.SByte4); +Assert.IsNonNegative(k.SByte5); +Assert.IsNonNegative(k.SByte6); +Assert.IsNonNegative(k.SByte7); +Assert.IsNonNegative(n.SByte4); +Assert.IsNonNegative(n.SByte5); +Assert.IsNonNegative(n.SByte6); +Assert.IsNonNegative(n.SByte7); +} +if (elements > 8) +{ +Assert.IsNotGreater(k.SByte8, n.SByte8); +Assert.IsNotGreater(k.SByte9, n.SByte9); +Assert.IsNotGreater(k.SByte10, n.SByte10); +Assert.IsNotGreater(k.SByte11, n.SByte11); +Assert.IsNotGreater(k.SByte12, n.SByte12); +Assert.IsNotGreater(k.SByte13, n.SByte13); +Assert.IsNotGreater(k.SByte14, n.SByte14); +Assert.IsNotGreater(k.SByte15, n.SByte15); +Assert.IsNonNegative(k.SByte8); +Assert.IsNonNegative(k.SByte9); +Assert.IsNonNegative(k.SByte10); +Assert.IsNonNegative(k.SByte11); +Assert.IsNonNegative(k.SByte12); +Assert.IsNonNegative(k.SByte13); +Assert.IsNonNegative(k.SByte14); +Assert.IsNonNegative(k.SByte15); +Assert.IsNonNegative(n.SByte8); +Assert.IsNonNegative(n.SByte9); +Assert.IsNonNegative(n.SByte10); +Assert.IsNonNegative(n.SByte11); +Assert.IsNonNegative(n.SByte12); +Assert.IsNonNegative(n.SByte13); +Assert.IsNonNegative(n.SByte14); +Assert.IsNonNegative(n.SByte15); +} + + if (unsafeLevels > 0 || constexpr.ALL_LE_EPU8(n, MAX_INVERSE_FACTORIAL_U64, elements)) + { + if (unsafeLevels > 1 || constexpr.ALL_LE_EPU8(n, MAX_INVERSE_FACTORIAL_U32, elements)) + { + if (unsafeLevels > 2 || constexpr.ALL_LE_EPU8(n, MAX_INVERSE_FACTORIAL_U16, elements)) + { + if (unsafeLevels > 3 || constexpr.ALL_LE_EPU8(n, MAX_INVERSE_FACTORIAL_U8, elements)) + { + return naivecomb_epu8(n, k, elements); + } + else + { + if (elements <= 8) + { + return cvtepi16_epi8(naivecomb_epu16(cvtepu8_epi16(n), cvtepu8_epi16(k), false, elements), elements); + } + else + { + if (Avx2.IsAvx2Supported) + { + return mm256_cvtepi16_epi8(mm256_naivecomb_epu16(Avx2.mm256_cvtepu8_epi16(n), Avx2.mm256_cvtepu8_epi16(k), false)); + } + else + { + v128 nLo16 = cvt2x2epu8_epi16(n, out v128 nHi16); + v128 kLo16 = cvt2x2epu8_epi16(k, out v128 kHi16); + + v128 resultLo = naivecomb_epu16(nLo16, kLo16, false, elements); + v128 resultHi = naivecomb_epu16(nHi16, kHi16, false, elements); + + return cvt2x2epi16_epi8(resultLo, resultHi); + } + } + } + } + else + { + if (elements <= 4) + { + return cvtepi32_epi8(naivecomb_epu32(cvtepu8_epi32(n), cvtepu8_epi32(k), elements)); + } + else + { + if (Avx2.IsAvx2Supported) + { + if (elements == 8) + { + return mm256_cvtepi32_epi8(mm256_naivecomb_epu32(Avx2.mm256_cvtepu8_epi32(n), Avx2.mm256_cvtepu8_epi32(k))); + } + else + { + v256 loN32 = Avx2.mm256_cvtepu8_epi32(n); + v256 hiN32 = Avx2.mm256_cvtepu8_epi32(Sse2.bsrli_si128(n, 8 * sizeof(byte))); + v256 loK32 = Avx2.mm256_cvtepu8_epi32(k); + v256 hiK32 = Avx2.mm256_cvtepu8_epi32(Sse2.bsrli_si128(k, 8 * sizeof(byte))); + + v128 resultLo = mm256_cvtepi32_epi8(mm256_naivecomb_epu32(loN32, loK32)); + v128 resultHi = mm256_cvtepi32_epi8(mm256_naivecomb_epu32(hiN32, hiK32)); + + return Sse2.unpacklo_epi64(resultLo, resultHi); + } + } + else + { + if (elements == 8) + { + v128 loN32 = cvtepu8_epi32(n); + v128 hiN32 = cvtepu8_epi32(Sse2.bsrli_si128(n, 4 * sizeof(byte))); + v128 loK32 = cvtepu8_epi32(k); + v128 hiK32 = cvtepu8_epi32(Sse2.bsrli_si128(k, 4 * sizeof(byte))); + + v128 resultLo = naivecomb_epu32(loN32, loK32); + v128 resultHi = naivecomb_epu32(hiN32, hiK32); + + v128 result = cvt2x2epi32_epi16(resultLo, resultHi); + + return cvt2x2epi16_epi8(result, result); + } + else + { + v128 loN16 = cvt2x2epu8_epi16(n, out v128 hiN16); + v128 loK16 = cvt2x2epu8_epi16(k, out v128 hiK16); + + v128 n32_0 = cvt2x2epu16_epi32(loN16, out v128 n32_1); + v128 n32_2 = cvt2x2epu16_epi32(hiN16, out v128 n32_3); + v128 k32_0 = cvt2x2epu16_epi32(loK16, out v128 k32_1); + v128 k32_2 = cvt2x2epu16_epi32(hiK16, out v128 k32_3); + + v128 result32_0 = naivecomb_epu32(n32_0, k32_0); + v128 result32_1 = naivecomb_epu32(n32_1, k32_1); + v128 result32_2 = naivecomb_epu32(n32_2, k32_2); + v128 result32_3 = naivecomb_epu32(n32_3, k32_3); + + v128 result16_0 = cvt2x2epi32_epi16(result32_0, result32_1); + v128 result16_1 = cvt2x2epi32_epi16(result32_2, result32_3); + + return cvt2x2epi16_epi8(result16_0, result16_1); + } + } + } + } + } + else + { + switch (elements) + { + case 2: + { + return Sse2.unpacklo_epi8(Sse2.cvtsi64x_si128((long)maxmath.comb((ulong)extract_epi8(n, 0), (ulong)extract_epi8(k, 0), maxmath.Promise.Unsafe0)), + Sse2.cvtsi64x_si128((long)maxmath.comb((ulong)extract_epi8(n, 1), (ulong)extract_epi8(k, 1), maxmath.Promise.Unsafe0))); + } + + case 3: + case 4: + { + if (Avx2.IsAvx2Supported) + { + return mm256_cvtepi64_epi8(mm256_naivecomb_epu64(Avx2.mm256_cvtepu8_epi64(n), Avx2.mm256_cvtepu8_epi64(k), elements)); + } + else + { + return new v128((byte)maxmath.comb((ulong)extract_epi8(n, 0), (ulong)extract_epi8(k, 0), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 1), (ulong)extract_epi8(k, 1), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 2), (ulong)extract_epi8(k, 2), maxmath.Promise.Unsafe0), + (byte)(elements == 4 ? maxmath.comb((ulong)extract_epi8(n, 3), (ulong)extract_epi8(k, 3), maxmath.Promise.Unsafe0) : 0), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0); + } + } + + case 8: + { + if (Avx2.IsAvx2Supported) + { + v256 n64Lo = Avx2.mm256_cvtepu8_epi64(n); + v256 k64Lo = Avx2.mm256_cvtepu8_epi64(k); + v256 n64Hi = Avx2.mm256_cvtepu8_epi64(Sse2.bsrli_si128(n, 4 * sizeof(byte))); + v256 k64Hi = Avx2.mm256_cvtepu8_epi64(Sse2.bsrli_si128(k, 4 * sizeof(byte))); + + v128 lo = mm256_cvtepi64_epi8(mm256_naivecomb_epu64(n64Lo, k64Lo)); + v128 hi = mm256_cvtepi64_epi8(mm256_naivecomb_epu64(n64Hi, k64Hi)); + + return Sse2.unpacklo_epi32(lo, hi); + } + else + { + return new v128((byte)maxmath.comb((ulong)extract_epi8(n, 0), (ulong)extract_epi8(k, 0), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 1), (ulong)extract_epi8(k, 1), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 2), (ulong)extract_epi8(k, 2), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 3), (ulong)extract_epi8(k, 3), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 4), (ulong)extract_epi8(k, 4), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 5), (ulong)extract_epi8(k, 5), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 6), (ulong)extract_epi8(k, 6), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 7), (ulong)extract_epi8(k, 7), maxmath.Promise.Unsafe0), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0); + } + } + + default: + { + if (Avx2.IsAvx2Supported) + { + v256 n0 = Avx2.mm256_cvtepu8_epi64(n); + v256 k0 = Avx2.mm256_cvtepu8_epi64(k); + v256 n1 = Avx2.mm256_cvtepu8_epi64(Sse2.bsrli_si128(n, 4 * sizeof(byte))); + v256 k1 = Avx2.mm256_cvtepu8_epi64(Sse2.bsrli_si128(k, 4 * sizeof(byte))); + v256 n2 = Avx2.mm256_cvtepu8_epi64(Sse2.bsrli_si128(n, 8 * sizeof(byte))); + v256 k2 = Avx2.mm256_cvtepu8_epi64(Sse2.bsrli_si128(k, 8 * sizeof(byte))); + v256 n3 = Avx2.mm256_cvtepu8_epi64(Sse2.bsrli_si128(n, 12 * sizeof(byte))); + v256 k3 = Avx2.mm256_cvtepu8_epi64(Sse2.bsrli_si128(k, 12 * sizeof(byte))); + + v128 result0 = mm256_cvtepi64_epi8(mm256_naivecomb_epu64(n0, k0)); + v128 result1 = mm256_cvtepi64_epi8(mm256_naivecomb_epu64(n1, k1)); + v128 result2 = mm256_cvtepi64_epi8(mm256_naivecomb_epu64(n2, k2)); + v128 result3 = mm256_cvtepi64_epi8(mm256_naivecomb_epu64(n3, k3)); + + return Sse2.unpacklo_epi64(Sse2.unpacklo_epi32(result0, result1), Sse2.unpacklo_epi32(result2, result3)); + } + else + { + return new v128((byte)maxmath.comb((ulong)extract_epi8(n, 0), (ulong)extract_epi8(k, 0), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 1), (ulong)extract_epi8(k, 1), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 2), (ulong)extract_epi8(k, 2), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 3), (ulong)extract_epi8(k, 3), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 4), (ulong)extract_epi8(k, 4), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 5), (ulong)extract_epi8(k, 5), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 6), (ulong)extract_epi8(k, 6), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 7), (ulong)extract_epi8(k, 7), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 8), (ulong)extract_epi8(k, 8), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 9), (ulong)extract_epi8(k, 9), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 10), (ulong)extract_epi8(k, 10), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 11), (ulong)extract_epi8(k, 11), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 12), (ulong)extract_epi8(k, 12), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 13), (ulong)extract_epi8(k, 13), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 14), (ulong)extract_epi8(k, 14), maxmath.Promise.Unsafe0), + (byte)maxmath.comb((ulong)extract_epi8(n, 15), (ulong)extract_epi8(k, 15), maxmath.Promise.Unsafe0)); + } + } + } + } + } + + + if (elements <= 8) + { + return cvtepi16_epi8(comb_epi16(cvtepu8_epi16(n), cvtepu8_epi16(k), elements: elements), elements); + } + else + { + if (Avx2.IsAvx2Supported) + { + return mm256_cvtepi16_epi8(mm256_comb_epi16(Avx2.mm256_cvtepu8_epi16(n), Avx2.mm256_cvtepu8_epi16(k))); + } + else + { + v128 ONE = Sse2.set1_epi8(1); + + k = Sse2.min_epu8(k, Sse2.sub_epi8(n, k)); + + v128 n2 = n; + n = Sse2.sub_epi8(n, ONE); + v128 c = Sse2.add_epi8(mullo_epi8(srli_epi8(n2, 1), n, 16), Sse2.and_si128(neg_epi8(Sse2.and_si128(n2, ONE)), srli_epi8(n, 1))); + v128 results = blendv_si128(blendv_si128(c, n2, Sse2.cmpeq_epi8(k, ONE)), ONE, Sse2.cmpeq_epi8(k, Sse2.setzero_si128())); + v128 i = Sse2.add_epi8(ONE, ONE); + v128 cmp = Sse2.cmpgt_epi8(k, i); + + while (Hint.Likely(notallfalse_epi128(cmp, 16))) + { + i = Sse2.add_epi8(i, ONE); + v128 q = divrem_epu8(c, i, out v128 r); + n = Sse2.sub_epi8(n, ONE); + c = Sse2.add_epi8(mullo_epi8(q, n, 16), div_epu8(mullo_epi8(r, n, 16), i)); + + results = blendv_si128(results, c, cmp); + cmp = Sse2.cmpgt_epi8(k, i); + } + + return results; + } + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_comb_epi8(v256 n, v256 k, byte unsafeLevels = 0) + { + if (Avx2.IsAvx2Supported) + { +Assert.IsNotGreater(k.SByte0, n.SByte0); +Assert.IsNotGreater(k.SByte1, n.SByte1); +Assert.IsNotGreater(k.SByte2, n.SByte2); +Assert.IsNotGreater(k.SByte3, n.SByte3); +Assert.IsNotGreater(k.SByte4, n.SByte4); +Assert.IsNotGreater(k.SByte5, n.SByte5); +Assert.IsNotGreater(k.SByte6, n.SByte6); +Assert.IsNotGreater(k.SByte7, n.SByte7); +Assert.IsNotGreater(k.SByte8, n.SByte8); +Assert.IsNotGreater(k.SByte9, n.SByte9); +Assert.IsNotGreater(k.SByte10, n.SByte10); +Assert.IsNotGreater(k.SByte11, n.SByte11); +Assert.IsNotGreater(k.SByte12, n.SByte12); +Assert.IsNotGreater(k.SByte13, n.SByte13); +Assert.IsNotGreater(k.SByte14, n.SByte14); +Assert.IsNotGreater(k.SByte15, n.SByte15); +Assert.IsNotGreater(k.SByte16, n.SByte16); +Assert.IsNotGreater(k.SByte17, n.SByte17); +Assert.IsNotGreater(k.SByte18, n.SByte18); +Assert.IsNotGreater(k.SByte19, n.SByte19); +Assert.IsNotGreater(k.SByte20, n.SByte20); +Assert.IsNotGreater(k.SByte21, n.SByte21); +Assert.IsNotGreater(k.SByte22, n.SByte22); +Assert.IsNotGreater(k.SByte23, n.SByte23); +Assert.IsNotGreater(k.SByte24, n.SByte24); +Assert.IsNotGreater(k.SByte25, n.SByte25); +Assert.IsNotGreater(k.SByte26, n.SByte26); +Assert.IsNotGreater(k.SByte27, n.SByte27); +Assert.IsNotGreater(k.SByte28, n.SByte28); +Assert.IsNotGreater(k.SByte29, n.SByte29); +Assert.IsNotGreater(k.SByte30, n.SByte30); +Assert.IsNotGreater(k.SByte31, n.SByte31); +Assert.IsNonNegative(k.SByte0); +Assert.IsNonNegative(k.SByte1); +Assert.IsNonNegative(k.SByte2); +Assert.IsNonNegative(k.SByte3); +Assert.IsNonNegative(k.SByte4); +Assert.IsNonNegative(k.SByte5); +Assert.IsNonNegative(k.SByte6); +Assert.IsNonNegative(k.SByte7); +Assert.IsNonNegative(k.SByte8); +Assert.IsNonNegative(k.SByte9); +Assert.IsNonNegative(k.SByte10); +Assert.IsNonNegative(k.SByte11); +Assert.IsNonNegative(k.SByte12); +Assert.IsNonNegative(k.SByte13); +Assert.IsNonNegative(k.SByte14); +Assert.IsNonNegative(k.SByte15); +Assert.IsNonNegative(k.SByte16); +Assert.IsNonNegative(k.SByte17); +Assert.IsNonNegative(k.SByte18); +Assert.IsNonNegative(k.SByte19); +Assert.IsNonNegative(k.SByte20); +Assert.IsNonNegative(k.SByte21); +Assert.IsNonNegative(k.SByte22); +Assert.IsNonNegative(k.SByte23); +Assert.IsNonNegative(k.SByte24); +Assert.IsNonNegative(k.SByte25); +Assert.IsNonNegative(k.SByte26); +Assert.IsNonNegative(k.SByte27); +Assert.IsNonNegative(k.SByte28); +Assert.IsNonNegative(k.SByte29); +Assert.IsNonNegative(k.SByte30); +Assert.IsNonNegative(k.SByte31); +Assert.IsNonNegative(n.SByte0); +Assert.IsNonNegative(n.SByte1); +Assert.IsNonNegative(n.SByte2); +Assert.IsNonNegative(n.SByte3); +Assert.IsNonNegative(n.SByte4); +Assert.IsNonNegative(n.SByte5); +Assert.IsNonNegative(n.SByte6); +Assert.IsNonNegative(n.SByte7); +Assert.IsNonNegative(n.SByte8); +Assert.IsNonNegative(n.SByte9); +Assert.IsNonNegative(n.SByte10); +Assert.IsNonNegative(n.SByte11); +Assert.IsNonNegative(n.SByte12); +Assert.IsNonNegative(n.SByte13); +Assert.IsNonNegative(n.SByte14); +Assert.IsNonNegative(n.SByte15); +Assert.IsNonNegative(n.SByte16); +Assert.IsNonNegative(n.SByte17); +Assert.IsNonNegative(n.SByte18); +Assert.IsNonNegative(n.SByte19); +Assert.IsNonNegative(n.SByte20); +Assert.IsNonNegative(n.SByte21); +Assert.IsNonNegative(n.SByte22); +Assert.IsNonNegative(n.SByte23); +Assert.IsNonNegative(n.SByte24); +Assert.IsNonNegative(n.SByte25); +Assert.IsNonNegative(n.SByte26); +Assert.IsNonNegative(n.SByte27); +Assert.IsNonNegative(n.SByte28); +Assert.IsNonNegative(n.SByte29); +Assert.IsNonNegative(n.SByte30); +Assert.IsNonNegative(n.SByte31); + + if (unsafeLevels > 0 || constexpr.ALL_LE_EPU8(n, MAX_INVERSE_FACTORIAL_U64)) + { + if (unsafeLevels > 1 || constexpr.ALL_LE_EPU8(n, MAX_INVERSE_FACTORIAL_U32)) + { + if (unsafeLevels > 2 || constexpr.ALL_LE_EPU8(n, MAX_INVERSE_FACTORIAL_U16)) + { + if (unsafeLevels > 3 || constexpr.ALL_LE_EPU8(n, MAX_INVERSE_FACTORIAL_U8)) + { + return mm256_naivecomb_epu8(n, k); + } + else + { + v256 nLo16 = mm256_cvt2x2epu8_epi16(n, out v256 nHi16); + v256 kLo16 = mm256_cvt2x2epu8_epi16(k, out v256 kHi16); + + return mm256_cvt2x2epi16_epi8(mm256_naivecomb_epu16(nLo16, kLo16), mm256_naivecomb_epu16(nHi16, kHi16)); + } + } + else + { + v256 loN16 = mm256_cvt2x2epu8_epi16(n, out v256 hiN16); + v256 loK16 = mm256_cvt2x2epu8_epi16(k, out v256 hiK16); + + v256 n32_0 = mm256_cvt2x2epu16_epi32(loN16, out v256 n32_1); + v256 n32_2 = mm256_cvt2x2epu16_epi32(hiN16, out v256 n32_3); + v256 k32_0 = mm256_cvt2x2epu16_epi32(loK16, out v256 k32_1); + v256 k32_2 = mm256_cvt2x2epu16_epi32(hiK16, out v256 k32_3); + + v256 result32_0 = mm256_naivecomb_epu32(n32_0, k32_0); + v256 result32_1 = mm256_naivecomb_epu32(n32_1, k32_1); + v256 result32_2 = mm256_naivecomb_epu32(n32_2, k32_2); + v256 result32_3 = mm256_naivecomb_epu32(n32_3, k32_3); + + v256 result16_0 = mm256_cvt2x2epi32_epi16(result32_0, result32_1); + v256 result16_1 = mm256_cvt2x2epi32_epi16(result32_2, result32_3); + + return mm256_cvt2x2epi16_epi8(result16_0, result16_1); + } + } + else + { + v256 loN16 = mm256_cvt2x2epu8_epi16(n, out v256 hiN16); + v256 loK16 = mm256_cvt2x2epu8_epi16(k, out v256 hiK16); + + v256 n32_0 = mm256_cvt2x2epu16_epi32(loN16, out v256 n32_1); + v256 n32_2 = mm256_cvt2x2epu16_epi32(hiN16, out v256 n32_3); + v256 k32_0 = mm256_cvt2x2epu16_epi32(loK16, out v256 k32_1); + v256 k32_2 = mm256_cvt2x2epu16_epi32(hiK16, out v256 k32_3); + + v256 n64_0 = mm256_cvt2x2epu32_epi64(n32_0, out v256 n64_1); + v256 n64_2 = mm256_cvt2x2epu32_epi64(n32_1, out v256 n64_3); + v256 n64_4 = mm256_cvt2x2epu32_epi64(n32_2, out v256 n64_5); + v256 n64_6 = mm256_cvt2x2epu32_epi64(n32_3, out v256 n64_7); + v256 k64_0 = mm256_cvt2x2epu32_epi64(k32_0, out v256 k64_1); + v256 k64_2 = mm256_cvt2x2epu32_epi64(k32_1, out v256 k64_3); + v256 k64_4 = mm256_cvt2x2epu32_epi64(k32_2, out v256 k64_5); + v256 k64_6 = mm256_cvt2x2epu32_epi64(k32_3, out v256 k64_7); + + v256 result64_0 = mm256_naivecomb_epu64(n64_0, k64_0); + v256 result64_1 = mm256_naivecomb_epu64(n64_1, k64_1); + v256 result64_2 = mm256_naivecomb_epu64(n64_2, k64_2); + v256 result64_3 = mm256_naivecomb_epu64(n64_3, k64_3); + v256 result64_4 = mm256_naivecomb_epu64(n64_4, k64_4); + v256 result64_5 = mm256_naivecomb_epu64(n64_5, k64_5); + v256 result64_6 = mm256_naivecomb_epu64(n64_6, k64_6); + v256 result64_7 = mm256_naivecomb_epu64(n64_7, k64_7); + + v256 result32_0 = mm256_cvt2x2epi64_epi32(result64_0, result64_1); + v256 result32_1 = mm256_cvt2x2epi64_epi32(result64_2, result64_3); + v256 result32_2 = mm256_cvt2x2epi64_epi32(result64_4, result64_5); + v256 result32_3 = mm256_cvt2x2epi64_epi32(result64_6, result64_7); + + v256 result16_0 = mm256_cvt2x2epi32_epi16(result32_0, result32_1); + v256 result16_1 = mm256_cvt2x2epi32_epi16(result32_2, result32_3); + + return mm256_cvt2x2epi16_epi8(result16_0, result16_1); + } + } + + + v256 ONE = Avx.mm256_set1_epi8(1); + + k = Avx2.mm256_min_epu8(k, Avx2.mm256_sub_epi8(n, k)); + + v256 n2 = n; + n = Avx2.mm256_sub_epi8(n, ONE); + v256 c = Avx2.mm256_add_epi8(mm256_mullo_epi8(mm256_srli_epi8(n2, 1), n), Avx2.mm256_and_si256(mm256_neg_epi8(Avx2.mm256_and_si256(n2, ONE)), mm256_srli_epi8(n, 1))); + v256 results = mm256_blendv_si256(mm256_blendv_si256(c, n2, Avx2.mm256_cmpeq_epi8(k, ONE)), ONE, Avx2.mm256_cmpeq_epi8(k, Avx.mm256_setzero_si256())); + v256 i = Avx2.mm256_add_epi8(ONE, ONE); + v256 cmp = Avx2.mm256_cmpgt_epi8(k, i); + + while (Hint.Likely(mm256_notallfalse_epi256(cmp, 32))) + { + i = Avx2.mm256_add_epi8(i, ONE); + v256 q = mm256_divrem_epu8(c, i, out v256 r); + n = Avx2.mm256_sub_epi8(n, ONE); + c = Avx2.mm256_add_epi8(mm256_mullo_epi8(q, n), mm256_div_epu8(mm256_mullo_epi8(r, n), i)); + + results = mm256_blendv_si256(results, c, cmp); + cmp = Avx2.mm256_cmpgt_epi8(k, i); + } + + return results; + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 comb_epu16(v128 n, v128 k, byte unsafeLevels = 0, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { +Assert.IsNotGreater(k.UShort0, n.UShort0); +Assert.IsNotGreater(k.UShort1, n.UShort1); +if (elements > 2) +{ +Assert.IsNotGreater(k.UShort2, n.UShort2); +} +if (elements > 3) +{ +Assert.IsNotGreater(k.UShort3, n.UShort3); +} +if (elements > 4) +{ +Assert.IsNotGreater(k.UShort4, n.UShort4); +Assert.IsNotGreater(k.UShort5, n.UShort5); +Assert.IsNotGreater(k.UShort6, n.UShort6); +Assert.IsNotGreater(k.UShort7, n.UShort7); +} + + if (unsafeLevels != 0 || constexpr.ALL_LE_EPU16(n, (ushort)short.MaxValue, elements)) + { + return comb_epi16(n, k, unsafeLevels, elements); + } + else + { + v128 ONE = Sse2.set1_epi16(1); + + k = min_epu16(k, Sse2.sub_epi16(n, k)); + + v128 n2 = n; + n = Sse2.sub_epi16(n, ONE); + v128 c = Sse2.add_epi16(Sse2.mullo_epi16(Sse2.srli_epi16(n2, 1), n), Sse2.and_si128(neg_epi16(Sse2.and_si128(n2, ONE)), Sse2.srli_epi16(n, 1))); + v128 results = blendv_si128(blendv_si128(c, n2, Sse2.cmpeq_epi16(k, ONE)), ONE, Sse2.cmpeq_epi16(k, Sse2.setzero_si128())); + v128 i = Sse2.add_epi16(ONE, ONE); + + if (Sse4_1.IsSse41Supported) + { + v128 cmp = cmple_epu16(k, i); + while (Hint.Likely(notalltrue_epi128(cmp, 8))) + { + i = Sse2.add_epi16(i, ONE); + v128 q = divrem_epu16(c, i, out v128 r); + n = Sse2.sub_epi16(n, ONE); + c = Sse2.add_epi16(Sse2.mullo_epi16(q, n), div_epu16(Sse2.mullo_epi16(r, n), i)); + + results = blendv_si128(c, results, cmp); + cmp = cmple_epu16(k, i); + } + } + else + { + v128 cmp = cmpgt_epu16(k, i); + while (Hint.Likely(notallfalse_epi128(cmp, 8))) + { + i = Sse2.add_epi16(i, ONE); + v128 q = divrem_epu16(c, i, out v128 r); + n = Sse2.sub_epi16(n, ONE); + c = Sse2.add_epi16(Sse2.mullo_epi16(q, n), div_epu16(Sse2.mullo_epi16(r, n), i)); + + results = blendv_si128(results, c, cmp); + cmp = cmpgt_epu16(k, i); + } + } + + + return results; + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_comb_epu16(v256 n, v256 k, byte unsafeLevels = 0) + { + if (Avx2.IsAvx2Supported) + { +Assert.IsNotGreater(k.UShort0, n.UShort0); +Assert.IsNotGreater(k.UShort1, n.UShort1); +Assert.IsNotGreater(k.UShort2, n.UShort2); +Assert.IsNotGreater(k.UShort3, n.UShort3); +Assert.IsNotGreater(k.UShort4, n.UShort4); +Assert.IsNotGreater(k.UShort5, n.UShort5); +Assert.IsNotGreater(k.UShort6, n.UShort6); +Assert.IsNotGreater(k.UShort7, n.UShort7); +Assert.IsNotGreater(k.UShort8, n.UShort8); +Assert.IsNotGreater(k.UShort9, n.UShort9); +Assert.IsNotGreater(k.UShort10, n.UShort10); +Assert.IsNotGreater(k.UShort11, n.UShort11); +Assert.IsNotGreater(k.UShort12, n.UShort12); +Assert.IsNotGreater(k.UShort13, n.UShort13); +Assert.IsNotGreater(k.UShort14, n.UShort14); +Assert.IsNotGreater(k.UShort15, n.UShort15); + + if (unsafeLevels != 0 || constexpr.ALL_LE_EPU16(n, (ushort)short.MaxValue)) + { + return mm256_comb_epi16(n, k, unsafeLevels); + } + else + { + v256 ONE = Avx.mm256_set1_epi16(1); + + k = Avx2.mm256_min_epu16(k, Avx2.mm256_sub_epi16(n, k)); + + v256 n2 = n; + n = Avx2.mm256_sub_epi16(n, ONE); + v256 c = Avx2.mm256_add_epi16(Avx2.mm256_mullo_epi16(Avx2.mm256_srli_epi16(n2, 1), n), Avx2.mm256_and_si256(mm256_neg_epi16(Avx2.mm256_and_si256(n2, ONE)), Avx2.mm256_srli_epi16(n, 1))); + v256 results = mm256_blendv_si256(mm256_blendv_si256(c, n2, Avx2.mm256_cmpeq_epi16(k, ONE)), ONE, Avx2.mm256_cmpeq_epi16(k, Avx.mm256_setzero_si256())); + v256 i = Avx2.mm256_add_epi16(ONE, ONE); + v256 cmp = mm256_cmple_epu16(k, i); + + while (Hint.Likely(mm256_notalltrue_epi256(cmp, 16))) + { + i = Avx2.mm256_add_epi16(i, ONE); + v256 q = mm256_divrem_epu16(c, i, out v256 r); + n = Avx2.mm256_sub_epi16(n, ONE); + c = Avx2.mm256_add_epi16(Avx2.mm256_mullo_epi16(q, n), mm256_div_epu16(Avx2.mm256_mullo_epi16(r, n), i)); + + results = mm256_blendv_si256(c, results, cmp); + cmp = mm256_cmple_epu16(k, i); + } + + return results; + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 comb_epi16(v128 n, v128 k, byte unsafeLevels = 0, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { +Assert.IsNotGreater(k.SShort0, n.SShort0); +Assert.IsNotGreater(k.SShort1, n.SShort1); +Assert.IsNonNegative(k.SShort0); +Assert.IsNonNegative(n.SShort0); +Assert.IsNonNegative(k.SShort1); +Assert.IsNonNegative(n.SShort1); +if (elements > 2) +{ +Assert.IsNotGreater(k.SShort2, n.SShort2); +Assert.IsNonNegative(k.SShort2); +Assert.IsNonNegative(n.SShort2); +} +if (elements > 3) +{ +Assert.IsNotGreater(k.SShort3, n.SShort3); +Assert.IsNonNegative(k.SShort3); +Assert.IsNonNegative(n.SShort3); +} +if (elements > 4) +{ +Assert.IsNotGreater(k.SShort4, n.SShort4); +Assert.IsNotGreater(k.SShort5, n.SShort5); +Assert.IsNotGreater(k.SShort6, n.SShort6); +Assert.IsNotGreater(k.SShort7, n.SShort7); +Assert.IsNonNegative(k.SShort4); +Assert.IsNonNegative(k.SShort5); +Assert.IsNonNegative(k.SShort6); +Assert.IsNonNegative(k.SShort7); +Assert.IsNonNegative(n.SShort4); +Assert.IsNonNegative(n.SShort5); +Assert.IsNonNegative(n.SShort6); +Assert.IsNonNegative(n.SShort7); +} + + if (unsafeLevels > 0 || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U64, elements)) + { + if (unsafeLevels > 1 || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U32, elements)) + { + if (unsafeLevels > 2 || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U16, elements)) + { + return naivecomb_epu16(n, k, unsafeLevels > 3 || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U8, elements), elements); + } + else + { + if (elements <= 4) + { + return cvtepi32_epi16(naivecomb_epu32(cvtepu16_epi32(n), cvtepu16_epi32(k), elements), elements); + } + else + { + if (Avx2.IsAvx2Supported) + { + return mm256_cvtepi32_epi16(mm256_naivecomb_epu32(Avx2.mm256_cvtepu16_epi32(n), Avx2.mm256_cvtepu16_epi32(k))); + } + else + { + v128 nLo32 = cvt2x2epu16_epi32(n, out v128 nHi32); + v128 kLo32 = cvt2x2epu16_epi32(k, out v128 kHi32); + + return cvt2x2epi32_epi16(naivecomb_epu32(nLo32, kLo32), naivecomb_epu32(nHi32, kHi32)); + } + } + } + } + else + { + switch (elements) + { + case 2: + { + return Sse2.unpacklo_epi16(Sse2.cvtsi32_si128((int)maxmath.comb((ulong)extract_epi16(n, 0), (ulong)extract_epi16(k, 0), maxmath.Promise.Unsafe0)), + Sse2.cvtsi32_si128((int)maxmath.comb((ulong)extract_epi16(n, 1), (ulong)extract_epi16(k, 1), maxmath.Promise.Unsafe0))); + } + + case 3: + case 4: + { + if (Avx2.IsAvx2Supported) + { + return mm256_cvtepi64_epi16(mm256_naivecomb_epu64(Avx2.mm256_cvtepu16_epi64(n), Avx2.mm256_cvtepu16_epi64(k), elements)); + } + else + { + return new v128((ushort)maxmath.comb((ulong)extract_epi16(n, 0), (ulong)extract_epi16(k, 0), maxmath.Promise.Unsafe0), + (ushort)maxmath.comb((ulong)extract_epi16(n, 1), (ulong)extract_epi16(k, 1), maxmath.Promise.Unsafe0), + (ushort)maxmath.comb((ulong)extract_epi16(n, 2), (ulong)extract_epi16(k, 2), maxmath.Promise.Unsafe0), + (ushort)(elements == 4 ? maxmath.comb((ulong)extract_epi16(n, 3), (ulong)extract_epi16(k, 3), maxmath.Promise.Unsafe0) : 0), + 0, + 0, + 0, + 0); + } + } + + default: + { + if (Avx2.IsAvx2Supported) + { + v256 n64Lo = Avx2.mm256_cvtepu16_epi64(n); + v256 k64Lo = Avx2.mm256_cvtepu16_epi64(k); + v256 n64Hi = Avx2.mm256_cvtepu16_epi64(Sse2.bsrli_si128(n, 4 * sizeof(ushort))); + v256 k64Hi = Avx2.mm256_cvtepu16_epi64(Sse2.bsrli_si128(k, 4 * sizeof(ushort))); + + v128 result64Lo = mm256_cvtepi64_epi16(mm256_naivecomb_epu64(n64Lo, k64Lo)); + v128 result64Hi = mm256_cvtepi64_epi16(mm256_naivecomb_epu64(n64Hi, k64Hi)); + + return Sse2.unpacklo_epi64(result64Lo, result64Hi); + } + else + { + return new v128((ushort)maxmath.comb((ulong)extract_epi16(n, 0), (ulong)extract_epi16(k, 0), maxmath.Promise.Unsafe0), + (ushort)maxmath.comb((ulong)extract_epi16(n, 1), (ulong)extract_epi16(k, 1), maxmath.Promise.Unsafe0), + (ushort)maxmath.comb((ulong)extract_epi16(n, 2), (ulong)extract_epi16(k, 2), maxmath.Promise.Unsafe0), + (ushort)maxmath.comb((ulong)extract_epi16(n, 3), (ulong)extract_epi16(k, 3), maxmath.Promise.Unsafe0), + (ushort)maxmath.comb((ulong)extract_epi16(n, 4), (ulong)extract_epi16(k, 4), maxmath.Promise.Unsafe0), + (ushort)maxmath.comb((ulong)extract_epi16(n, 5), (ulong)extract_epi16(k, 5), maxmath.Promise.Unsafe0), + (ushort)maxmath.comb((ulong)extract_epi16(n, 6), (ulong)extract_epi16(k, 6), maxmath.Promise.Unsafe0), + (ushort)maxmath.comb((ulong)extract_epi16(n, 7), (ulong)extract_epi16(k, 7), maxmath.Promise.Unsafe0)); + } + } + } + } + } + + + v128 ONE = Sse2.set1_epi16(1); + + k = Sse2.min_epi16(k, Sse2.sub_epi16(n, k)); + + v128 n2 = n; + n = Sse2.sub_epi16(n, ONE); + v128 c = Sse2.add_epi16(Sse2.mullo_epi16(Sse2.srli_epi16(n2, 1), n), Sse2.and_si128(neg_epi16(Sse2.and_si128(n2, ONE)), Sse2.srli_epi16(n, 1))); + v128 results = blendv_si128(blendv_si128(c, n2, Sse2.cmpeq_epi16(k, ONE)), ONE, Sse2.cmpeq_epi16(k, Sse2.setzero_si128())); + v128 i = Sse2.add_epi16(ONE, ONE); + v128 cmp = Sse2.cmpgt_epi16(k, i); + + while (Hint.Likely(notallfalse_epi128(cmp, elements))) + { + i = Sse2.add_epi16(i, ONE); + v128 q = divrem_epu16(c, i, out v128 r, elements); + n = Sse2.sub_epi16(n, ONE); + c = Sse2.add_epi16(Sse2.mullo_epi16(q, n), div_epu16(Sse2.mullo_epi16(r, n), i, elements)); + + results = blendv_si128(results, c, cmp); + cmp = Sse2.cmpgt_epi16(k, i); + } + + return results; + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_comb_epi16(v256 n, v256 k, byte unsafeLevels = 0) + { + if (Avx2.IsAvx2Supported) + { +Assert.IsNotGreater(k.SShort0, n.SShort0); +Assert.IsNotGreater(k.SShort1, n.SShort1); +Assert.IsNotGreater(k.SShort2, n.SShort2); +Assert.IsNotGreater(k.SShort3, n.SShort3); +Assert.IsNotGreater(k.SShort4, n.SShort4); +Assert.IsNotGreater(k.SShort5, n.SShort5); +Assert.IsNotGreater(k.SShort6, n.SShort6); +Assert.IsNotGreater(k.SShort7, n.SShort7); +Assert.IsNotGreater(k.SShort8, n.SShort8); +Assert.IsNotGreater(k.SShort9, n.SShort9); +Assert.IsNotGreater(k.SShort10, n.SShort10); +Assert.IsNotGreater(k.SShort11, n.SShort11); +Assert.IsNotGreater(k.SShort12, n.SShort12); +Assert.IsNotGreater(k.SShort13, n.SShort13); +Assert.IsNotGreater(k.SShort14, n.SShort14); +Assert.IsNotGreater(k.SShort15, n.SShort15); +Assert.IsNonNegative(k.SShort0); +Assert.IsNonNegative(k.SShort1); +Assert.IsNonNegative(k.SShort2); +Assert.IsNonNegative(k.SShort3); +Assert.IsNonNegative(k.SShort4); +Assert.IsNonNegative(k.SShort5); +Assert.IsNonNegative(k.SShort6); +Assert.IsNonNegative(k.SShort7); +Assert.IsNonNegative(k.SShort8); +Assert.IsNonNegative(k.SShort9); +Assert.IsNonNegative(k.SShort10); +Assert.IsNonNegative(k.SShort11); +Assert.IsNonNegative(k.SShort12); +Assert.IsNonNegative(k.SShort13); +Assert.IsNonNegative(k.SShort14); +Assert.IsNonNegative(k.SShort15); +Assert.IsNonNegative(n.SShort0); +Assert.IsNonNegative(n.SShort1); +Assert.IsNonNegative(n.SShort2); +Assert.IsNonNegative(n.SShort3); +Assert.IsNonNegative(n.SShort4); +Assert.IsNonNegative(n.SShort5); +Assert.IsNonNegative(n.SShort6); +Assert.IsNonNegative(n.SShort7); +Assert.IsNonNegative(n.SShort8); +Assert.IsNonNegative(n.SShort9); +Assert.IsNonNegative(n.SShort10); +Assert.IsNonNegative(n.SShort11); +Assert.IsNonNegative(n.SShort12); +Assert.IsNonNegative(n.SShort13); +Assert.IsNonNegative(n.SShort14); +Assert.IsNonNegative(n.SShort15); + + if (unsafeLevels > 0 || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U64)) + { + if (unsafeLevels > 1 || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U32)) + { + if (unsafeLevels > 2 || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U16)) + { + return mm256_naivecomb_epu16(n, k, unsafeLevels > 3 || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U8)); + } + else + { + v256 nLo32 = mm256_cvt2x2epu16_epi32(n, out v256 nHi32); + v256 kLo32 = mm256_cvt2x2epu16_epi32(k, out v256 kHi32); + + v256 resultLo = mm256_naivecomb_epu32(nLo32, kLo32); + v256 resultHi = mm256_naivecomb_epu32(nHi32, kHi32); + + return mm256_cvt2x2epi32_epi16(resultLo, resultHi); + } + } + else + { + v256 nLo32 = mm256_cvt2x2epu16_epi32(n, out v256 nHi32); + v256 kLo32 = mm256_cvt2x2epu16_epi32(k, out v256 kHi32); + v256 n64LoLo = mm256_cvt2x2epu32_epi64(nLo32, out v256 n64LoHi); + v256 n64HiLo = mm256_cvt2x2epu32_epi64(nHi32, out v256 n64HiHi); + v256 k64LoLo = mm256_cvt2x2epu32_epi64(kLo32, out v256 k64LoHi); + v256 k64HiLo = mm256_cvt2x2epu32_epi64(kHi32, out v256 k64HiHi); + + v256 resultLoLo = mm256_naivecomb_epu64(n64LoLo, k64LoLo); + v256 resultLoHi = mm256_naivecomb_epu64(n64LoHi, k64LoHi); + v256 resultHiLo = mm256_naivecomb_epu64(n64HiLo, k64HiLo); + v256 resultHiHi = mm256_naivecomb_epu64(n64HiHi, k64HiHi); + + v256 result32Lo = mm256_cvt2x2epi64_epi32(resultLoLo, resultLoHi); + v256 result32Hi = mm256_cvt2x2epi64_epi32(resultHiLo, resultHiHi); + + return mm256_cvt2x2epi32_epi16(result32Lo, result32Hi); + } + } + + + v256 ONE = Avx.mm256_set1_epi16(1); + + k = Avx2.mm256_min_epu16(k, Avx2.mm256_sub_epi16(n, k)); + + v256 n2 = n; + n = Avx2.mm256_sub_epi16(n, ONE); + v256 c = Avx2.mm256_add_epi16(Avx2.mm256_mullo_epi16(Avx2.mm256_srli_epi16(n2, 1), n), Avx2.mm256_and_si256(mm256_neg_epi16(Avx2.mm256_and_si256(n2, ONE)), Avx2.mm256_srli_epi16(n, 1))); + v256 results = mm256_blendv_si256(mm256_blendv_si256(c, n2, Avx2.mm256_cmpeq_epi16(k, ONE)), ONE, Avx2.mm256_cmpeq_epi16(k, Avx.mm256_setzero_si256())); + v256 i = Avx2.mm256_add_epi16(ONE, ONE); + v256 cmp = Avx2.mm256_cmpgt_epi16(k, i); + + while (Hint.Likely(mm256_notallfalse_epi256(cmp, 16))) + { + i = Avx2.mm256_add_epi16(i, ONE); + v256 q = mm256_divrem_epu16(c, i, out v256 r); + n = Avx2.mm256_sub_epi16(n, ONE); + c = Avx2.mm256_add_epi16(Avx2.mm256_mullo_epi16(q, n), mm256_div_epu16(Avx2.mm256_mullo_epi16(r, n), i)); + + results = mm256_blendv_si256(results, c, cmp); + cmp = Avx2.mm256_cmpgt_epi16(k, i); + } + + return results; + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 comb_epi32(v128 n, v128 k, byte unsafeLevels = 0, byte elements = 4) + { + if (Sse2.IsSse2Supported) + { +Assert.IsNotGreater(k.SInt0, n.SInt0); +Assert.IsNotGreater(k.SInt1, n.SInt1); +Assert.IsNonNegative(k.SInt0); +Assert.IsNonNegative(k.SInt1); +Assert.IsNonNegative(n.SInt0); +Assert.IsNonNegative(n.SInt1); +if (elements > 2) +{ +Assert.IsNotGreater(k.SInt2, n.SInt2); +Assert.IsNonNegative(k.SInt2); +Assert.IsNonNegative(n.SInt2); +} +if (elements > 3) +{ +Assert.IsNotGreater(k.SInt3, n.SInt3); +Assert.IsNonNegative(k.SInt3); +Assert.IsNonNegative(n.SInt3); +} + + if (unsafeLevels > 0 || constexpr.ALL_LE_EPU32(n, MAX_INVERSE_FACTORIAL_U64, elements)) + { + if (unsafeLevels > 1 || constexpr.ALL_LE_EPU32(n, MAX_INVERSE_FACTORIAL_U32, elements)) + { + return naivecomb_epu32(n, k, elements); + } + else + { + if (elements > 2) + { + if (Avx2.IsAvx2Supported) + { + return mm256_cvtepi64_epi32(mm256_naivecomb_epu64(Avx2.mm256_cvtepu32_epi64(n), Avx2.mm256_cvtepu32_epi64(k), elements)); + } + else + { + v128 lo = Sse2.unpacklo_epi32(Sse2.cvtsi32_si128((int)maxmath.comb((ulong)extract_epi32(n, 0), (ulong)extract_epi32(k, 0), maxmath.Promise.Unsafe0)), + Sse2.cvtsi32_si128((int)maxmath.comb((ulong)extract_epi32(n, 1), (ulong)extract_epi32(k, 1), maxmath.Promise.Unsafe0))); + v128 hi = Sse2.cvtsi32_si128((int)maxmath.comb((ulong)extract_epi32(n, 2), (ulong)extract_epi32(k, 2), maxmath.Promise.Unsafe0)); + + if (elements == 4) + { + hi = Sse2.unpacklo_epi32(hi, Sse2.cvtsi32_si128((int)maxmath.comb((ulong)extract_epi32(n, 3), (ulong)extract_epi32(k, 3), maxmath.Promise.Unsafe0))); + } + + return Sse2.unpacklo_epi64(lo, hi); + } + } + else + { + return Sse2.unpacklo_epi32(Sse2.cvtsi32_si128((int)maxmath.comb((ulong)extract_epi32(n, 0), (ulong)extract_epi32(k, 0), maxmath.Promise.Unsafe0)), + Sse2.cvtsi32_si128((int)maxmath.comb((ulong)extract_epi32(n, 1), (ulong)extract_epi32(k, 1), maxmath.Promise.Unsafe0))); + } + } + } + + + v128 ONE = Sse2.set1_epi32(1); + + k = min_epi32(k, Sse2.sub_epi32(n, k)); + + v128 n2 = n; + n = Sse2.sub_epi32(n, ONE); + v128 c = Sse2.add_epi32(mullo_epi32(Sse2.srli_epi32(n2, 1), n, elements), Sse2.and_si128(neg_epi32(Sse2.and_si128(n2, ONE)), Sse2.srli_epi32(n, 1))); + v128 results = blendv_si128(blendv_si128(c, n2, Sse2.cmpeq_epi32(k, ONE)), ONE, Sse2.cmpeq_epi32(k, Sse2.setzero_si128())); + v128 i = Sse2.add_epi32(ONE, ONE); + v128 cmp = Sse2.cmpgt_epi32(k, i); + + while (Hint.Likely(notallfalse_epi128(cmp, elements))) + { + i = Sse2.add_epi32(i, ONE); + v128 q = divrem_epu32(c, i, out v128 r, elements); + n = Sse2.sub_epi32(n, ONE); + c = Sse2.add_epi32(mullo_epi32(q, n, elements), div_epu32(mullo_epi32(r, n, elements), i, elements)); + + results = blendv_si128(results, c, cmp); + cmp = Sse2.cmpgt_epi32(k, i); + } + + return results; + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_comb_epi32(v256 n, v256 k, byte unsafeLevels = 0) + { + if (Avx2.IsAvx2Supported) + { +Assert.IsNotGreater(k.SInt0, n.SInt0); +Assert.IsNotGreater(k.SInt1, n.SInt1); +Assert.IsNotGreater(k.SInt2, n.SInt2); +Assert.IsNotGreater(k.SInt3, n.SInt3); +Assert.IsNotGreater(k.SInt4, n.SInt4); +Assert.IsNotGreater(k.SInt5, n.SInt5); +Assert.IsNotGreater(k.SInt6, n.SInt6); +Assert.IsNotGreater(k.SInt7, n.SInt7); +Assert.IsNonNegative(k.SInt0); +Assert.IsNonNegative(k.SInt1); +Assert.IsNonNegative(k.SInt2); +Assert.IsNonNegative(k.SInt3); +Assert.IsNonNegative(k.SInt4); +Assert.IsNonNegative(k.SInt5); +Assert.IsNonNegative(k.SInt6); +Assert.IsNonNegative(k.SInt7); +Assert.IsNonNegative(n.SInt0); +Assert.IsNonNegative(n.SInt1); +Assert.IsNonNegative(n.SInt2); +Assert.IsNonNegative(n.SInt3); +Assert.IsNonNegative(n.SInt4); +Assert.IsNonNegative(n.SInt5); +Assert.IsNonNegative(n.SInt6); +Assert.IsNonNegative(n.SInt7); + + if (unsafeLevels > 0 || constexpr.ALL_LE_EPU32(n, MAX_INVERSE_FACTORIAL_U64)) + { + if (unsafeLevels > 1 || constexpr.ALL_LE_EPU32(n, MAX_INVERSE_FACTORIAL_U32)) + { + return mm256_naivecomb_epu32(n, k); + } + else + { + v256 n64Lo = mm256_cvt2x2epu32_epi64(n, out v256 n64Hi); + v256 k64Lo = mm256_cvt2x2epu32_epi64(k, out v256 k64Hi); + + v256 resultLo = mm256_naivecomb_epu64(n64Lo, k64Lo); + v256 resultHi = mm256_naivecomb_epu64(n64Hi, k64Hi); + + return mm256_cvt2x2epi64_epi32(resultLo, resultHi); + } + } + + + v256 ONE = Avx.mm256_set1_epi32(1); + + k = Avx2.mm256_min_epi32(k, Avx2.mm256_sub_epi32(n, k)); + + v256 n2 = n; + n = Avx2.mm256_sub_epi32(n, ONE); + v256 c = Avx2.mm256_add_epi32(Avx2.mm256_mullo_epi32(Avx2.mm256_srli_epi32(n2, 1), n), Avx2.mm256_and_si256(mm256_neg_epi32(Avx2.mm256_and_si256(n2, ONE)), Avx2.mm256_srli_epi32(n, 1))); + v256 results = mm256_blendv_si256(mm256_blendv_si256(c, n2, Avx2.mm256_cmpeq_epi32(k, ONE)), ONE, Avx2.mm256_cmpeq_epi32(k, Avx.mm256_setzero_si256())); + v256 i = Avx2.mm256_add_epi32(ONE, ONE); + v256 cmp = Avx2.mm256_cmpgt_epi32(k, i); + + while (Hint.Likely(mm256_notallfalse_epi256(cmp, 8))) + { + i = Avx2.mm256_add_epi32(i, ONE); + v256 q = mm256_divrem_epu32(c, i, out v256 r); + n = Avx2.mm256_sub_epi32(n, ONE); + c = Avx2.mm256_add_epi32(Avx2.mm256_mullo_epi32(q, n), mm256_div_epu32(Avx2.mm256_mullo_epi32(r, n), i)); + + results = mm256_blendv_si256(results, c, cmp); + cmp = Avx2.mm256_cmpgt_epi32(k, i); + } + + return results; + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 comb_epu32(v128 n, v128 k, byte unsafeLevels = 0, byte elements = 4) + { + if (Sse2.IsSse2Supported) + { +Assert.IsNotGreater(k.UInt0, n.UInt0); +Assert.IsNotGreater(k.UInt1, n.UInt1); +if (elements > 2) +{ +Assert.IsNotGreater(k.UInt2, n.UInt2); +} +if (elements > 3) +{ +Assert.IsNotGreater(k.UInt3, n.UInt3); +} + + if (unsafeLevels != 0 || constexpr.ALL_LE_EPU32(n, int.MaxValue)) + { + return comb_epi32(n, k, unsafeLevels, elements); + } + else + { + v128 ONE = Sse2.set1_epi32(1); + + k = min_epu32(k, Sse2.sub_epi32(n, k)); + + v128 n2 = n; + n = Sse2.sub_epi32(n, ONE); + v128 c = Sse2.add_epi32(mullo_epi32(Sse2.srli_epi32(n2, 1), n, elements), Sse2.and_si128(neg_epi32(Sse2.and_si128(n2, ONE)), Sse2.srli_epi32(n, 1))); + v128 results = blendv_si128(blendv_si128(c, n2, Sse2.cmpeq_epi32(k, ONE)), ONE, Sse2.cmpeq_epi32(k, Sse2.setzero_si128())); + v128 i = Sse2.add_epi32(ONE, ONE); + + if (Sse4_1.IsSse41Supported) + { + v128 cmp = cmple_epu32(k, i, elements); + while (Hint.Likely(notalltrue_epi128(cmp, elements))) + { + i = Sse2.add_epi32(i, ONE); + v128 q = divrem_epu32(c, i, out v128 r); + n = Sse2.sub_epi32(n, ONE); + c = Sse2.add_epi32(mullo_epi32(q, n, elements), div_epu32(mullo_epi32(r, n, elements), i, elements)); + + results = blendv_si128(c, results, cmp); + cmp = cmple_epu32(k, i, elements); + } + } + else + { + v128 cmp = cmpgt_epu32(k, i, elements); + while (Hint.Likely(notallfalse_epi128(cmp, elements))) + { + i = Sse2.add_epi32(i, ONE); + v128 q = divrem_epu32(c, i, out v128 r); + n = Sse2.sub_epi32(n, ONE); + c = Sse2.add_epi32(mullo_epi32(q, n, elements), div_epu32(mullo_epi32(r, n, elements), i, elements)); + + results = blendv_si128(results, c, cmp); + cmp = cmpgt_epu32(k, i, elements); + } + } + + return results; + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_comb_epu32(v256 n, v256 k, byte unsafeLevels = 0) + { + if (Avx2.IsAvx2Supported) + { +Assert.IsNotGreater(k.UInt0, n.UInt0); +Assert.IsNotGreater(k.UInt1, n.UInt1); +Assert.IsNotGreater(k.UInt2, n.UInt2); +Assert.IsNotGreater(k.UInt3, n.UInt3); +Assert.IsNotGreater(k.UInt4, n.UInt4); +Assert.IsNotGreater(k.UInt5, n.UInt5); +Assert.IsNotGreater(k.UInt6, n.UInt6); +Assert.IsNotGreater(k.UInt7, n.UInt7); + + if (unsafeLevels != 0 || constexpr.ALL_LE_EPU32(n, int.MaxValue)) + { + return mm256_comb_epi32(n, k, unsafeLevels); + } + else + { + v256 ONE = Avx.mm256_set1_epi32(1); + + k = Avx2.mm256_min_epu32(k, Avx2.mm256_sub_epi32(n, k)); + + v256 n2 = n; + n = Avx2.mm256_sub_epi32(n, ONE); + v256 c = Avx2.mm256_add_epi32(Avx2.mm256_mullo_epi32(Avx2.mm256_srli_epi32(n2, 1), n), Avx2.mm256_and_si256(mm256_neg_epi32(Avx2.mm256_and_si256(n2, ONE)), Avx2.mm256_srli_epi32(n, 1))); + v256 results = mm256_blendv_si256(mm256_blendv_si256(c, n2, Avx2.mm256_cmpeq_epi32(k, ONE)), ONE, Avx2.mm256_cmpeq_epi32(k, Avx.mm256_setzero_si256())); + v256 i = Avx2.mm256_add_epi32(ONE, ONE); + v256 cmp = mm256_cmple_epu32(k, i); + + while (Hint.Likely(mm256_notalltrue_epi256(cmp, 8))) + { + i = Avx2.mm256_add_epi32(i, ONE); + v256 q = mm256_divrem_epu32(c, i, out v256 r); + n = Avx2.mm256_sub_epi32(n, ONE); + c = Avx2.mm256_add_epi32(Avx2.mm256_mullo_epi32(q, n), mm256_div_epu32(Avx2.mm256_mullo_epi32(r, n), i)); + + results = mm256_blendv_si256(c, results, cmp); + cmp = mm256_cmple_epu32(k, i); + } + + return results; + } + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 comb_epi64(v128 n, v128 k, byte unsafeLevels = 0) + { + if (Sse2.IsSse2Supported) + { +Assert.IsNotGreater(k.SLong0, n.SLong0); +Assert.IsNotGreater(k.SLong1, n.SLong1); +Assert.IsNonNegative(k.SLong0); +Assert.IsNonNegative(k.SLong1); +Assert.IsNonNegative(n.SLong0); +Assert.IsNonNegative(n.SLong1); + + if (unsafeLevels > 0 || constexpr.ALL_LE_EPU64(n, MAX_INVERSE_FACTORIAL_U64)) + { + if (unsafeLevels > 1 || constexpr.ALL_LE_EPU64(n, MAX_INVERSE_FACTORIAL_U32)) + { + v128 nFactorial = gamma_epu64(n, true); + v128 kFactorial = gamma_epu64(k, true); + v128 nkFactorial = gamma_epu64(Sse2.sub_epi64(n, k), true); + + return usfcvttpd_epu64(Sse2.div_pd(usfcvtepu64_pd(nFactorial), usfcvtepu64_pd(mullo_epi64(kFactorial, nkFactorial)))); + } + else + { + return Sse2.unpacklo_epi64(Sse2.cvtsi64x_si128((long)maxmath.comb(extract_epi64(n, 0), extract_epi64(k, 0), maxmath.Promise.Unsafe0)), + Sse2.cvtsi64x_si128((long)maxmath.comb(extract_epi64(n, 1), extract_epi64(k, 1), maxmath.Promise.Unsafe0))); + } + } + + + v128 ONE = Sse2.set1_epi64x(1); + + k = min_epi64(k, Sse2.sub_epi64(n, k)); + + v128 n2 = n; + n = Sse2.sub_epi64(n, ONE); + v128 c = Sse2.add_epi64(mullo_epi64(Sse2.srli_epi64(n2, 1), n), Sse2.and_si128(neg_epi64(Sse2.and_si128(n2, ONE)), Sse2.srli_epi64(n, 1))); + v128 results = blendv_si128(blendv_si128(c, n2, cmpeq_epi64(k, ONE)), ONE, cmpeq_epi64(k, Sse2.setzero_si128())); + v128 i = Sse2.add_epi64(ONE, ONE); + v128 cmp = cmpgt_epi64(k, i); + + while (Hint.Likely(notallfalse_epi128(cmp, 2))) + { + i = Sse2.add_epi64(i, ONE); + v128 q = divrem_epu64(c, i, out v128 r); + n = Sse2.sub_epi64(n, ONE); + c = Sse2.add_epi64(mullo_epi64(q, n), div_epu64(mullo_epi64(r, n), i)); + + results = blendv_si128(results, c, cmp); + cmp = cmpgt_epi64(k, i); + } + + return results; + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_comb_epi64(v256 n, v256 k, byte unsafeLevels = 0, byte elements = 4) + { + if (Avx2.IsAvx2Supported) + { +Assert.IsNotGreater(k.SLong0, n.SLong0); +Assert.IsNotGreater(k.SLong1, n.SLong1); +Assert.IsNotGreater(k.SLong2, n.SLong2); +Assert.IsNonNegative(k.SLong0); +Assert.IsNonNegative(k.SLong1); +Assert.IsNonNegative(k.SLong2); +Assert.IsNonNegative(n.SLong0); +Assert.IsNonNegative(n.SLong1); +Assert.IsNonNegative(n.SLong2); +if (elements > 3) +{ + Assert.IsNotGreater(k.SLong3, n.SLong3); + Assert.IsNonNegative(k.SLong3); + Assert.IsNonNegative(n.SLong3); +} + if (unsafeLevels > 0 || constexpr.ALL_LE_EPU64(n, MAX_INVERSE_FACTORIAL_U64)) + { + if (unsafeLevels > 1 || constexpr.ALL_LE_EPU64(n, MAX_INVERSE_FACTORIAL_U32)) + { + v256 nFactorial = mm256_gamma_epu64(n, true); + v256 kFactorial = mm256_gamma_epu64(k, true); + v256 nkFactorial = mm256_gamma_epu64(Avx2.mm256_sub_epi64(n, k), true); + + return mm256_usfcvttpd_epu64(Avx.mm256_div_pd(mm256_usfcvtepu64_pd(nFactorial), mm256_usfcvtepu64_pd(mm256_mullo_epi64(kFactorial, nkFactorial, elements)))); + } + else + { + return mm256_naivecomb_epu64(n, k, elements); + } + } + + + v256 ONE = Avx.mm256_set1_epi64x(1); + + k = mm256_min_epi64(k, Avx2.mm256_sub_epi64(n, k)); + + v256 n2 = n; + n = Avx2.mm256_sub_epi64(n, ONE); + v256 c = Avx2.mm256_add_epi64(mm256_mullo_epi64(Avx2.mm256_srli_epi64(n2, 1), n, elements), Avx2.mm256_and_si256(mm256_neg_epi64(Avx2.mm256_and_si256(n2, ONE)), Avx2.mm256_srli_epi64(n, 1))); + v256 results = mm256_blendv_si256(mm256_blendv_si256(c, n2, Avx2.mm256_cmpeq_epi64(k, ONE)), ONE, Avx2.mm256_cmpeq_epi64(k, Avx.mm256_setzero_si256())); + v256 i = Avx2.mm256_add_epi64(ONE, ONE); + v256 cmp = mm256_cmpgt_epi64(k, i, elements); + + while (Hint.Likely(mm256_notallfalse_epi256(cmp, elements))) + { + i = Avx2.mm256_add_epi64(i, ONE); + v256 q = mm256_divrem_epu64(c, i, out v256 r, elements); + n = Avx2.mm256_sub_epi64(n, ONE); + c = Avx2.mm256_add_epi64(mm256_mullo_epi64(q, n, elements), mm256_div_epu64(mm256_mullo_epi64(r, n, elements), i, elements)); + + results = mm256_blendv_si256(results, c, cmp); + cmp = mm256_cmpgt_epi64(k, i, elements); + } + + return results; + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 comb_epu64(v128 n, v128 k, byte unsafeLevels = 0) + { + if (Sse2.IsSse2Supported) + { +Assert.IsNotGreater(k.ULong0, n.ULong0); +Assert.IsNotGreater(k.ULong1, n.ULong1); + + if (unsafeLevels != 0 || constexpr.ALL_LE_EPU64(n, long.MaxValue)) + { + return comb_epi64(n, k, unsafeLevels); + } + else + { + v128 ONE = Sse2.set1_epi64x(1); + + k = min_epu64(k, Sse2.sub_epi64(n, k)); + + v128 n2 = n; + n = Sse2.sub_epi64(n, ONE); + v128 c = Sse2.add_epi64(mullo_epi64(Sse2.srli_epi64(n2, 1), n), Sse2.and_si128(neg_epi64(Sse2.and_si128(n2, ONE)), Sse2.srli_epi64(n, 1))); + v128 results = blendv_si128(blendv_si128(c, n2, cmpeq_epi64(k, ONE)), ONE, cmpeq_epi64(k, Sse2.setzero_si128())); + v128 i = Sse2.add_epi64(ONE, ONE); + v128 cmp = cmpgt_epu64(k, i); + + while (Hint.Likely(notallfalse_epi128(cmp, 2))) + { + i = Sse2.add_epi64(i, ONE); + v128 q = divrem_epu64(c, i, out v128 r); + n = Sse2.sub_epi64(n, ONE); + c = Sse2.add_epi64(mullo_epi64(q, n), div_epu64(mullo_epi64(r, n), i)); + + results = blendv_si128(results, c, cmp); + cmp = cmpgt_epu64(k, i); + } + + return results; + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_comb_epu64(v256 n, v256 k, byte unsafeLevels = 0, byte elements = 4) + { + if (Avx2.IsAvx2Supported) + { +Assert.IsNotGreater(k.ULong0, n.ULong0); +Assert.IsNotGreater(k.ULong1, n.ULong1); +Assert.IsNotGreater(k.ULong2, n.ULong2); +if (elements > 3) +{ + Assert.IsNotGreater(k.ULong3, n.ULong3); +} + if (unsafeLevels != 0 || constexpr.ALL_LE_EPU64(n, long.MaxValue, elements)) + { + return mm256_comb_epi64(n, k, unsafeLevels, elements); + } + else + { + v256 ONE = Avx.mm256_set1_epi64x(1); + + k = mm256_min_epu64(k, Avx2.mm256_sub_epi64(n, k)); + + v256 n2 = n; + n = Avx2.mm256_sub_epi64(n, ONE); + v256 c = Avx2.mm256_add_epi64(mm256_mullo_epi64(Avx2.mm256_srli_epi64(n2, 1), n, elements), Avx2.mm256_and_si256(mm256_neg_epi64(Avx2.mm256_and_si256(n2, ONE)), Avx2.mm256_srli_epi64(n, 1))); + v256 results = mm256_blendv_si256(mm256_blendv_si256(c, n2, Avx2.mm256_cmpeq_epi64(k, ONE)), ONE, Avx2.mm256_cmpeq_epi64(k, Avx.mm256_setzero_si256())); + v256 i = Avx2.mm256_add_epi64(ONE, ONE); + v256 cmp = mm256_cmpgt_epu64(k, i, elements); + + while (Hint.Likely(mm256_notallfalse_epi256(cmp, elements))) + { + i = Avx2.mm256_add_epi64(i, ONE); + v256 q = mm256_divrem_epu64(c, i, out v256 r, elements); + n = Avx2.mm256_sub_epi64(n, ONE); + c = Avx2.mm256_add_epi64(mm256_mullo_epi64(q, n, elements), mm256_div_epu64(mm256_mullo_epi64(r, n), i, elements)); + + results = mm256_blendv_si256(results, c, cmp); + cmp = mm256_cmpgt_epu64(k, i, elements); + } + + return results; + } + } + else throw new IllegalInstructionException(); + } + } + } + + + unsafe public static partial class maxmath + { + /// Returns the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 128 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 128 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt128 comb(UInt128 n, UInt128 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNotGreater(k, n); + + if (useFactorial.CountUnsafeLevels() > 0 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U128)) + { + return factorial(n, Promise.NoOverflow) / (factorial(k, Promise.NoOverflow) * factorial(n - k, Promise.NoOverflow)); + } + + + k = min(k, n - k); + if (Hint.Unlikely(k.IsZero)) + { + return 1; + } + + UInt128 c = n--; + + if (Hint.Likely(k > 1)) + { + c = ((c >> 1) * n) + (((UInt128)(-(Int128)(c & 1))) & (n >> 1)); + + UInt128 i = 2; + while (Hint.Likely(k > i++)) + { + UInt128 q = divrem(c, i, out UInt128 r); + n--; + c = (q * n) + ((r * n) / i); + } + } + + return c; + } + + /// Returns the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 128 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 128 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt128 comb(Int128 n, Int128 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsTrue(k >= 0); +Assert.IsTrue(n >= 0); + + return comb((UInt128)n, (UInt128)k, useFactorial); + } + + + /// Returns the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 64 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte comb(byte n, byte k, Promise useFactorial = Promise.Nothing) + { + if (useFactorial.CountUnsafeLevels() > 0 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U64)) + { + if (useFactorial.CountUnsafeLevels() > 1 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U32)) + { + if (useFactorial.CountUnsafeLevels() > 2 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U16)) + { + if (useFactorial.CountUnsafeLevels() > 3 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U8)) + { + return (byte)(factorial(n, Promise.NoOverflow) / (factorial(k, Promise.NoOverflow) * factorial((byte)(n - k), Promise.NoOverflow))); + } + else + { + return (byte)(factorial((ushort)n, Promise.NoOverflow) / (factorial((ushort)k, Promise.NoOverflow) * factorial((ushort)(n - k), Promise.NoOverflow))); + } + } + else + { + return (byte)(factorial((uint)n, Promise.NoOverflow) / (factorial((uint)k, Promise.NoOverflow) * factorial((uint)(n - k), Promise.NoOverflow))); + } + } + else + { + return (byte)(factorial((ulong)n, Promise.NoOverflow) / (factorial((ulong)k, Promise.NoOverflow) * factorial((ulong)(n - k), Promise.NoOverflow))); + } + } + + + k = min(k, (byte)(n - k)); + if (Hint.Unlikely(k == 0)) + { + return 1; + } + + byte c = n--; + + if (Hint.Likely(k > 1)) + { + c = (byte)((byte)((c >> 1) * n) + (byte)((-(c & 1)) & (n >> 1))); + + byte i = 2; + while (Hint.Likely(k > i++)) + { + byte q = divrem(c, i, out byte r); + n--; + c = (byte)((byte)(q * n) + (byte)((byte)(r * n) / i)); + } + } + + return c; + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 8 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte2 comb(byte2 n, byte2 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epu8(n, k, useFactorial.CountUnsafeLevels(), 2); + } + else + { + return new byte2(comb(n.x, k.x, useFactorial), + comb(n.y, k.y, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 8 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte3 comb(byte3 n, byte3 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epu8(n, k, useFactorial.CountUnsafeLevels(), 3); + } + else + { + return new byte3(comb(n.x, k.x, useFactorial), + comb(n.y, k.y, useFactorial), + comb(n.z, k.z, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 8 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte4 comb(byte4 n, byte4 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epu8(n, k, useFactorial.CountUnsafeLevels(), 4); + } + else + { + return new byte4(comb(n.x, k.x, useFactorial), + comb(n.y, k.y, useFactorial), + comb(n.z, k.z, useFactorial), + comb(n.w, k.w, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 8 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte8 comb(byte8 n, byte8 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epu8(n, k, useFactorial.CountUnsafeLevels(), 8); + } + else + { + return new byte8(comb(n.x0, k.x0, useFactorial), + comb(n.x1, k.x1, useFactorial), + comb(n.x2, k.x2, useFactorial), + comb(n.x3, k.x3, useFactorial), + comb(n.x4, k.x4, useFactorial), + comb(n.x5, k.x5, useFactorial), + comb(n.x6, k.x6, useFactorial), + comb(n.x7, k.x7, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 8 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte16 comb(byte16 n, byte16 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epu8(n, k, useFactorial.CountUnsafeLevels(), 16); + } + else + { + return new byte16(comb(n.x0, k.x0, useFactorial), + comb(n.x1, k.x1, useFactorial), + comb(n.x2, k.x2, useFactorial), + comb(n.x3, k.x3, useFactorial), + comb(n.x4, k.x4, useFactorial), + comb(n.x5, k.x5, useFactorial), + comb(n.x6, k.x6, useFactorial), + comb(n.x7, k.x7, useFactorial), + comb(n.x8, k.x8, useFactorial), + comb(n.x9, k.x9, useFactorial), + comb(n.x10, k.x10, useFactorial), + comb(n.x11, k.x11, useFactorial), + comb(n.x12, k.x12, useFactorial), + comb(n.x13, k.x13, useFactorial), + comb(n.x14, k.x14, useFactorial), + comb(n.x15, k.x15, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 8 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte32 comb(byte32 n, byte32 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_comb_epu8(n, k, useFactorial.CountUnsafeLevels()); + } + else + { + return new byte32(comb(n.v16_0, k.v16_0, useFactorial), + comb(n.v16_16, k.v16_16, useFactorial)); + } + } + + + /// Returns the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 64 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte comb(sbyte n, sbyte k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(k); +Assert.IsNonNegative(n); + + return comb((byte)n, (byte)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 8 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte2 comb(sbyte2 n, sbyte2 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epi8(n, k, useFactorial.CountUnsafeLevels(), 2); + } + else + { + return new byte2((byte)comb((int)n.x, (int)k.x, useFactorial), + (byte)comb((int)n.y, (int)k.y, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 8 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte3 comb(sbyte3 n, sbyte3 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epi8(n, k, useFactorial.CountUnsafeLevels(), 3); + } + else + { + return new byte3((byte)comb((int)n.x, (int)k.x, useFactorial), + (byte)comb((int)n.y, (int)k.y, useFactorial), + (byte)comb((int)n.z, (int)k.z, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 8 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte4 comb(sbyte4 n, sbyte4 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epi8(n, k, useFactorial.CountUnsafeLevels(), 4); + } + else + { + return new byte4((byte)comb((int)n.x, (int)k.x, useFactorial), + (byte)comb((int)n.y, (int)k.y, useFactorial), + (byte)comb((int)n.z, (int)k.z, useFactorial), + (byte)comb((int)n.w, (int)k.w, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 8 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte8 comb(sbyte8 n, sbyte8 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epi8(n, k, useFactorial.CountUnsafeLevels(), 8); + } + else + { + return new byte8((byte)comb((int)n.x0, (int)k.x0, useFactorial), + (byte)comb((int)n.x1, (int)k.x1, useFactorial), + (byte)comb((int)n.x2, (int)k.x2, useFactorial), + (byte)comb((int)n.x3, (int)k.x3, useFactorial), + (byte)comb((int)n.x4, (int)k.x4, useFactorial), + (byte)comb((int)n.x5, (int)k.x5, useFactorial), + (byte)comb((int)n.x6, (int)k.x6, useFactorial), + (byte)comb((int)n.x7, (int)k.x7, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 8 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte16 comb(sbyte16 n, sbyte16 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epi8(n, k, 16, useFactorial.CountUnsafeLevels()); + } + else + { + return new byte16((byte)comb((int)n.x0, (int)k.x0, useFactorial), + (byte)comb((int)n.x1, (int)k.x1, useFactorial), + (byte)comb((int)n.x2, (int)k.x2, useFactorial), + (byte)comb((int)n.x3, (int)k.x3, useFactorial), + (byte)comb((int)n.x4, (int)k.x4, useFactorial), + (byte)comb((int)n.x5, (int)k.x5, useFactorial), + (byte)comb((int)n.x6, (int)k.x6, useFactorial), + (byte)comb((int)n.x7, (int)k.x7, useFactorial), + (byte)comb((int)n.x8, (int)k.x8, useFactorial), + (byte)comb((int)n.x9, (int)k.x9, useFactorial), + (byte)comb((int)n.x10, (int)k.x10, useFactorial), + (byte)comb((int)n.x11, (int)k.x11, useFactorial), + (byte)comb((int)n.x12, (int)k.x12, useFactorial), + (byte)comb((int)n.x13, (int)k.x13, useFactorial), + (byte)comb((int)n.x14, (int)k.x14, useFactorial), + (byte)comb((int)n.x15, (int)k.x15, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 8 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte32 comb(sbyte32 n, sbyte32 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_comb_epi8(n, k, useFactorial.CountUnsafeLevels()); + } + else + { + return new byte32(comb(n.v16_0, k.v16_0, useFactorial), + comb(n.v16_16, k.v16_16, useFactorial)); + } + } + + + /// Returns the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 64 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort comb(ushort n, ushort k, Promise useFactorial = Promise.Nothing) + { + if (useFactorial.CountUnsafeLevels() > 0 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U64)) + { + if (useFactorial.CountUnsafeLevels() > 1 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U32)) + { + if (useFactorial.CountUnsafeLevels() > 2 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U16)) + { + if (useFactorial.CountUnsafeLevels() > 3 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U8)) + { + return (ushort)(factorial((byte)n, Promise.NoOverflow) / (factorial((byte)k, Promise.NoOverflow) * factorial((byte)(n - k), Promise.NoOverflow))); + } + else + { + return (ushort)(factorial(n, Promise.NoOverflow) / (factorial(k, Promise.NoOverflow) * factorial((ushort)(n - k), Promise.NoOverflow))); + } + } + else + { + return (ushort)(factorial((uint)n, Promise.NoOverflow) / (factorial((uint)k, Promise.NoOverflow) * factorial((uint)(n - k), Promise.NoOverflow))); + } + } + else + { + return (ushort)(factorial((ulong)n, Promise.NoOverflow) / (factorial((ulong)k, Promise.NoOverflow) * factorial((ulong)(n - k), Promise.NoOverflow))); + } + } + + + k = min(k, (ushort)(n - k)); + if (Hint.Unlikely(k == 0)) + { + return 1; + } + + ushort c = n--; + + if (Hint.Likely(k > 1)) + { + c = (ushort)((ushort)((c >> 1) * n) + (ushort)((-(c & 1)) & (n >> 1))); + + ushort i = 2; + while (Hint.Likely(k > i++)) + { + ushort q = divrem(c, i, out ushort r); + n--; + c = (ushort)((ushort)(q * n) + (ushort)((ushort)(r * n) / i)); + } + } + + return c; + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 16 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort2 comb(ushort2 n, ushort2 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epu16(n, k, useFactorial.CountUnsafeLevels(), 2); + } + else + { + return new ushort2(comb(n.x, k.x, useFactorial), + comb(n.y, k.y, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 16 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort3 comb(ushort3 n, ushort3 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epu16(n, k, useFactorial.CountUnsafeLevels(), 3); + } + else + { + return new ushort3(comb(n.x, k.x, useFactorial), + comb(n.y, k.y, useFactorial), + comb(n.z, k.z, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 16 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort4 comb(ushort4 n, ushort4 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epu16(n, k, useFactorial.CountUnsafeLevels(), 4); + } + else + { + return new ushort4(comb(n.x, k.x, useFactorial), + comb(n.y, k.y, useFactorial), + comb(n.z, k.z, useFactorial), + comb(n.w, k.w, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 16 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort8 comb(ushort8 n, ushort8 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epu16(n, k, useFactorial.CountUnsafeLevels(), 8); + } + else + { + return new ushort8(comb(n.x0, k.x0, useFactorial), + comb(n.x1, k.x1, useFactorial), + comb(n.x2, k.x2, useFactorial), + comb(n.x3, k.x3, useFactorial), + comb(n.x4, k.x4, useFactorial), + comb(n.x5, k.x5, useFactorial), + comb(n.x6, k.x6, useFactorial), + comb(n.x7, k.x7, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 16 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort16 comb(ushort16 n, ushort16 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_comb_epu16(n, k, useFactorial.CountUnsafeLevels()); + } + else + { + return new ushort16(comb(n.v8_0, k.v8_0, useFactorial), + comb(n.v8_8, k.v8_8, useFactorial)); + } + } + + + /// Returns the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 64 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort comb(short n, short k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(k); +Assert.IsNonNegative(n); + + return comb((short)n, (short)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 16 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort2 comb(short2 n, short2 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epi16(n, k, useFactorial.CountUnsafeLevels(), 2); + } + else + { + return new ushort2((ushort)comb((int)n.x, (int)k.x, useFactorial), + (ushort)comb((int)n.y, (int)k.y, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 16 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort3 comb(short3 n, short3 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epi16(n, k, useFactorial.CountUnsafeLevels(), 3); + } + else + { + return new ushort3((ushort)comb((int)n.x, (int)k.x, useFactorial), + (ushort)comb((int)n.y, (int)k.y, useFactorial), + (ushort)comb((int)n.z, (int)k.z, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 16 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort4 comb(short4 n, short4 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epi16(n, k, useFactorial.CountUnsafeLevels(), 4); + } + else + { + return new ushort4((ushort)comb((int)n.x, (int)k.x, useFactorial), + (ushort)comb((int)n.y, (int)k.y, useFactorial), + (ushort)comb((int)n.z, (int)k.z, useFactorial), + (ushort)comb((int)n.w, (int)k.w, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 16 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort8 comb(short8 n, short8 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epi16(n, k, useFactorial.CountUnsafeLevels(), 8); + } + else + { + return new ushort8((ushort)comb((int)n.x0, (int)k.x0, useFactorial), + (ushort)comb((int)n.x1, (int)k.x1, useFactorial), + (ushort)comb((int)n.x2, (int)k.x2, useFactorial), + (ushort)comb((int)n.x3, (int)k.x3, useFactorial), + (ushort)comb((int)n.x4, (int)k.x4, useFactorial), + (ushort)comb((int)n.x5, (int)k.x5, useFactorial), + (ushort)comb((int)n.x6, (int)k.x6, useFactorial), + (ushort)comb((int)n.x7, (int)k.x7, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 16 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort16 comb(short16 n, short16 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_comb_epi16(n, k, useFactorial.CountUnsafeLevels()); + } + else + { + return new ushort16(comb(n.v8_0, k.v8_0, useFactorial), + comb(n.v8_8, k.v8_8, useFactorial)); + } + } + + + /// Returns the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint comb(uint n, uint k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNotGreater(k, n); + + if (useFactorial.CountUnsafeLevels() > 0 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U64)) + { + if (useFactorial.CountUnsafeLevels() > 1 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U32)) + { + return factorial(n, Promise.NoOverflow) / (factorial(k, Promise.NoOverflow) * factorial(n - k, Promise.NoOverflow)); + } + else + { + return (uint)(factorial((ulong)n, Promise.NoOverflow) / (factorial((ulong)k, Promise.NoOverflow) * factorial((ulong)n - (ulong)k, Promise.NoOverflow))); + } + } + + + k = math.min(k, n - k); + if (Hint.Unlikely(k == 0)) + { + return 1; + } + + uint c = n--; + + if (Hint.Likely(k > 1)) + { + c = ((c >> 1) * n) + (((uint)-(int)(c & 1)) & (n >> 1)); + + uint i = 2; + while (Hint.Likely(k > i++)) + { + uint q = divrem(c, i, out uint r); + n--; + c = (q * n) + ((r * n) / i); + } + } + + return c; + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint2 comb(uint2 n, uint2 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt2(Xse.comb_epu32(RegisterConversion.ToV128(n), RegisterConversion.ToV128(k), useFactorial.CountUnsafeLevels(), 2)); + } + else + { + return new uint2(comb(n.x, k.x, useFactorial), + comb(n.y, k.y, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint3 comb(uint3 n, uint3 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt3(Xse.comb_epu32(RegisterConversion.ToV128(n), RegisterConversion.ToV128(k), useFactorial.CountUnsafeLevels(), 3)); + } + else + { + return new uint3(comb(n.x, k.x, useFactorial), + comb(n.y, k.y, useFactorial), + comb(n.z, k.z, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint4 comb(uint4 n, uint4 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt4(Xse.comb_epu32(RegisterConversion.ToV128(n), RegisterConversion.ToV128(k), useFactorial.CountUnsafeLevels(), 4)); + } + else + { + return new uint4(comb(n.x, k.x, useFactorial), + comb(n.y, k.y, useFactorial), + comb(n.z, k.z, useFactorial), + comb(n.w, k.w, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint8 comb(uint8 n, uint8 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_comb_epu32(n, k, useFactorial.CountUnsafeLevels()); + } + else + { + return new uint8(comb(n.v4_0, k.v4_0, useFactorial), + comb(n.v4_4, k.v4_4, useFactorial)); + } + } + + + /// Returns the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint comb(int n, int k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(k); +Assert.IsNonNegative(n); + + return comb((uint)n, (uint)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint2 comb(int2 n, int2 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt2(Xse.comb_epi32(RegisterConversion.ToV128(n), RegisterConversion.ToV128(k), useFactorial.CountUnsafeLevels(), 2)); + } + else + { + return new uint2(comb(n.x, k.x, useFactorial), + comb(n.y, k.y, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint3 comb(int3 n, int3 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt3(Xse.comb_epi32(RegisterConversion.ToV128(n), RegisterConversion.ToV128(k), useFactorial.CountUnsafeLevels(), 3)); + } + else + { + return new uint3(comb(n.x, k.x, useFactorial), + comb(n.y, k.y, useFactorial), + comb(n.z, k.z, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint4 comb(int4 n, int4 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt4(Xse.comb_epi32(RegisterConversion.ToV128(n), RegisterConversion.ToV128(k), useFactorial.CountUnsafeLevels(), 4)); + } + else + { + return new uint4(comb(n.x, k.x, useFactorial), + comb(n.y, k.y, useFactorial), + comb(n.z, k.z, useFactorial), + comb(n.w, k.w, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint8 comb(int8 n, int8 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_comb_epi32(n, k, useFactorial.CountUnsafeLevels()); + } + else + { + return new uint8(comb(n.v4_0, k.v4_0, useFactorial), + comb(n.v4_4, k.v4_4, useFactorial)); + } + } + + + /// Returns the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 64 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong comb(ulong n, ulong k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNotGreater(k, n); + + if (useFactorial.CountUnsafeLevels() > 0 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U64)) + { + if (useFactorial.CountUnsafeLevels() > 1 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U32)) + { + return (ulong)factorial((uint)n, Promise.NoOverflow) / (ulong)(factorial((uint)k, Promise.NoOverflow) * factorial((uint)n - (uint)k, Promise.NoOverflow)); + } + else + { + return factorial(n, Promise.NoOverflow) / (factorial(k, Promise.NoOverflow) * factorial(n - k, Promise.NoOverflow)); + } + } + + + k = math.min(k, n - k); + if (Hint.Unlikely(k == 0)) + { + return 1; + } + + ulong c = n--; + + if (Hint.Likely(k > 1)) + { + c = ((c >> 1) * n) + (((ulong)-(long)(c & 1)) & (n >> 1)); + + ulong i = 2; + while (Hint.Likely(k > i++)) + { + ulong q = divrem(c, i, out ulong r); + n--; + c = (q * n) + ((r * n) / i); + } + } + + return c; + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 64 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong2 comb(ulong2 n, ulong2 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epu64(n, k, useFactorial.CountUnsafeLevels()); + } + else + { + return new ulong2(comb(n.x, k.x, useFactorial), + comb(n.y, k.y, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 64 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong3 comb(ulong3 n, ulong3 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_comb_epu64(n, k, useFactorial.CountUnsafeLevels(), 3); + } + else + { + return new ulong3(comb(n.xy, k.xy, useFactorial), + comb(n.z, k.z, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 64 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong4 comb(ulong4 n, ulong4 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_comb_epu64(n, k, useFactorial.CountUnsafeLevels(), 4); + } + else + { + return new ulong4(comb(n.xy, k.xy, useFactorial), + comb(n.zw, k.zw, useFactorial)); + } + } + + + /// Returns the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 64 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong comb(long n, long k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(k); +Assert.IsNonNegative(n); + + return comb((ulong)n, (ulong)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 64 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong2 comb(long2 n, long2 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.comb_epi64(n, k, useFactorial.CountUnsafeLevels()); + } + else + { + return new ulong2(comb(n.x, k.x, useFactorial), + comb(n.y, k.y, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 64 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong3 comb(long3 n, long3 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_comb_epi64(n, k, useFactorial.CountUnsafeLevels(), 3); + } + else + { + return new ulong3(comb(n.xy, k.xy, useFactorial), + comb(n.z, k.z, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and without order. Also known as the binomial coefficient or " choose ". Arguments that produce an unsigned 64 bit overflow are undefined. + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong4 comb(long4 n, long4 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_comb_epi64(n, k, useFactorial.CountUnsafeLevels(), 4); + } + else + { + return new ulong4(comb(n.xy, k.xy, useFactorial), + comb(n.zw, k.zw, useFactorial)); + } + } + } +} \ No newline at end of file diff --git a/Runtime/XSE Core/Exceptions/ConstantException.cs.meta b/Runtime/Math Lib/Functions/Arithmetic/Integer/Binomial Coefficient.cs.meta similarity index 83% rename from Runtime/XSE Core/Exceptions/ConstantException.cs.meta rename to Runtime/Math Lib/Functions/Arithmetic/Integer/Binomial Coefficient.cs.meta index 12046d1..fefc02c 100644 --- a/Runtime/XSE Core/Exceptions/ConstantException.cs.meta +++ b/Runtime/Math Lib/Functions/Arithmetic/Integer/Binomial Coefficient.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a84bb5664b910d24bb32f94e36ed467b +guid: c4d25c32de54fac4f949642b84a6f54a MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Runtime/Math Lib/Functions/Arithmetic/Integer/Cube Root.cs b/Runtime/Math Lib/Functions/Arithmetic/Integer/Cube Root.cs index 4d07443..ebc0152 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Integer/Cube Root.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Integer/Cube Root.cs @@ -425,13 +425,13 @@ public static v256 mm256_cbrt_epi16(v256 a, bool promiseAbsolute = false, bool p [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v128 cbrt_epu32(v128 a, byte rangeLevelPromise = 0, byte elements = 4) + public static v128 cbrt_epu32(v128 a, byte rangePromiseLevel = 0, byte elements = 4) { if (Sse2.IsSse2Supported) { - if (rangeLevelPromise > 0 || constexpr.ALL_LE_EPU32(a, ushort.MaxValue, elements)) + if (rangePromiseLevel > 0 || constexpr.ALL_LE_EPU32(a, ushort.MaxValue, elements)) { - if (rangeLevelPromise > 1 || constexpr.ALL_LE_EPU32(a, byte.MaxValue, elements)) + if (rangePromiseLevel > 1 || constexpr.ALL_LE_EPU32(a, byte.MaxValue, elements)) { v128 ONE = Sse2.set1_epi32(1); @@ -619,13 +619,13 @@ public static v128 cbrt_epu32(v128 a, byte rangeLevelPromise = 0, byte elements } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v256 mm256_cbrt_epu32(v256 a, byte rangeLevelPromise = 0) + public static v256 mm256_cbrt_epu32(v256 a, byte rangePromiseLevel = 0) { if (Avx2.IsAvx2Supported) { - if (rangeLevelPromise > 0 || constexpr.ALL_LE_EPU32(a, ushort.MaxValue)) + if (rangePromiseLevel > 0 || constexpr.ALL_LE_EPU32(a, ushort.MaxValue)) { - if (rangeLevelPromise > 1 || constexpr.ALL_LE_EPU32(a, byte.MaxValue)) + if (rangePromiseLevel > 1 || constexpr.ALL_LE_EPU32(a, byte.MaxValue)) { v256 ONE = Avx.mm256_set1_epi32(1); @@ -814,24 +814,24 @@ public static v256 mm256_cbrt_epu32(v256 a, byte rangeLevelPromise = 0) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v128 cbrt_epi32(v128 a, bool promiseAbsolute = false, byte rangeLevelPromise = 0, byte elements = 4) + public static v128 cbrt_epi32(v128 a, bool promiseAbsolute = false, byte rangePromiseLevel = 0, byte elements = 4) { if (Sse2.IsSse2Supported) { if (promiseAbsolute || constexpr.ALL_GE_EPI32(a, 0, elements)) { - return cbrt_epu32(a, rangeLevelPromise, elements); + return cbrt_epu32(a, rangePromiseLevel, elements); } else { if (Ssse3.IsSsse3Supported) { - return Ssse3.sign_epi32(cbrt_epu32(Ssse3.abs_epi32(a), rangeLevelPromise, elements), a); + return Ssse3.sign_epi32(cbrt_epu32(Ssse3.abs_epi32(a), rangePromiseLevel, elements), a); } else { v128 negative = Sse2.srai_epi32(a, 31); - v128 cbrtAbs = cbrt_epu32(Sse2.xor_si128(Sse2.add_epi32(a, negative), negative), rangeLevelPromise, elements); + v128 cbrtAbs = cbrt_epu32(Sse2.xor_si128(Sse2.add_epi32(a, negative), negative), rangePromiseLevel, elements); return Sse2.xor_si128(Sse2.add_epi32(cbrtAbs, negative), negative); } @@ -841,7 +841,7 @@ public static v128 cbrt_epi32(v128 a, bool promiseAbsolute = false, byte rangeLe } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v256 mm256_cbrt_epi32(v256 a, bool promiseAbsolute = false, byte rangeLevelPromise = 0) + public static v256 mm256_cbrt_epi32(v256 a, bool promiseAbsolute = false, byte rangePromiseLevel = 0) { if (Avx2.IsAvx2Supported) { @@ -851,7 +851,7 @@ public static v256 mm256_cbrt_epi32(v256 a, bool promiseAbsolute = false, byte r } else { - return Avx2.mm256_sign_epi32(mm256_cbrt_epu32(Avx2.mm256_abs_epi32(a), rangeLevelPromise), a); + return Avx2.mm256_sign_epi32(mm256_cbrt_epu32(Avx2.mm256_abs_epi32(a), rangePromiseLevel), a); } } else throw new IllegalInstructionException(); @@ -859,17 +859,17 @@ public static v256 mm256_cbrt_epi32(v256 a, bool promiseAbsolute = false, byte r [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v128 cbrt_epu64(v128 a, byte rangeLevelPromise = 0) + public static v128 cbrt_epu64(v128 a, byte rangePromiseLevel = 0) { if (Sse2.IsSse2Supported) { - if (rangeLevelPromise > 0 || constexpr.ALL_LE_EPU64(a, 1ul << 40)) + if (rangePromiseLevel > 0 || constexpr.ALL_LE_EPU64(a, 1ul << 46)) { - if (rangeLevelPromise > 1 || constexpr.ALL_LE_EPU64(a, uint.MaxValue)) + if (rangePromiseLevel > 1 || constexpr.ALL_LE_EPU64(a, uint.MaxValue)) { - if (rangeLevelPromise > 2 || constexpr.ALL_LE_EPU64(a, ushort.MaxValue)) + if (rangePromiseLevel > 2 || constexpr.ALL_LE_EPU64(a, ushort.MaxValue)) { - if (rangeLevelPromise > 3 || constexpr.ALL_LE_EPU64(a, byte.MaxValue)) + if (rangePromiseLevel > 3 || constexpr.ALL_LE_EPU64(a, byte.MaxValue)) { return cbrt_epu8_takingAndReturning_epu16(a, 8); } @@ -885,7 +885,7 @@ public static v128 cbrt_epu64(v128 a, byte rangeLevelPromise = 0) } else { - // results within [0, 1ul << 40] have been proven to be correct empirically both with and without FMA instructions + // results within [0, 1ul << 46] have been proven to be correct empirically both with and without FMA instructions return usfcvttpd_epu64(cbrt_pd(usfcvtepu64_pd(a))); } } @@ -1092,17 +1092,17 @@ public static v128 cbrt_epu64(v128 a, byte rangeLevelPromise = 0) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v256 mm256_cbrt_epu64(v256 a, byte rangeLevelPromise = 0, byte elements = 4) + public static v256 mm256_cbrt_epu64(v256 a, byte rangePromiseLevel = 0, byte elements = 4) { if (Avx2.IsAvx2Supported) { - if (rangeLevelPromise > 0 || constexpr.ALL_LE_EPU64(a, 1ul << 40, elements)) + if (rangePromiseLevel > 0 || constexpr.ALL_LE_EPU64(a, 1ul << 46, elements)) { - if (rangeLevelPromise > 1 || constexpr.ALL_LE_EPU64(a, uint.MaxValue, elements)) + if (rangePromiseLevel > 1 || constexpr.ALL_LE_EPU64(a, uint.MaxValue, elements)) { - if (rangeLevelPromise > 2 || constexpr.ALL_LE_EPU64(a, ushort.MaxValue, elements)) + if (rangePromiseLevel > 2 || constexpr.ALL_LE_EPU64(a, ushort.MaxValue, elements)) { - if (rangeLevelPromise > 3 || constexpr.ALL_LE_EPU64(a, byte.MaxValue, elements)) + if (rangePromiseLevel > 3 || constexpr.ALL_LE_EPU64(a, byte.MaxValue, elements)) { return cbrt_epu8_takingAndReturning_epu16(a); } @@ -1118,7 +1118,7 @@ public static v256 mm256_cbrt_epu64(v256 a, byte rangeLevelPromise = 0, byte ele } else { - // results within [0, 1ul << 40] have been proven to be correct empirically both with and without FMA instructions + // results within [0, 1ul << 46] have been proven to be correct empirically both with and without FMA instructions return mm256_usfcvttpd_epu64(mm256_cbrt_pd(mm256_usfcvtepu64_pd(a))); } } @@ -1325,18 +1325,18 @@ public static v256 mm256_cbrt_epu64(v256 a, byte rangeLevelPromise = 0, byte ele } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v128 cbrt_epi64(v128 a, bool promiseAbs = false, byte rangeLevelPromise = 0) + public static v128 cbrt_epi64(v128 a, bool promiseAbs = false, byte rangePromiseLevel = 0) { if (Sse2.IsSse2Supported) { if (promiseAbs || constexpr.ALL_GE_EPI64(a, 0)) { - return cbrt_epu64(a, rangeLevelPromise); + return cbrt_epu64(a, rangePromiseLevel); } else { v128 negative = srai_epi64(a, 63); - v128 cbrtAbs = cbrt_epu64(Sse2.xor_si128(Sse2.add_epi64(a, negative), negative), rangeLevelPromise); + v128 cbrtAbs = cbrt_epu64(Sse2.xor_si128(Sse2.add_epi64(a, negative), negative), rangePromiseLevel); return Sse2.xor_si128(Sse2.add_epi64(cbrtAbs, negative), negative); } @@ -1345,18 +1345,18 @@ public static v128 cbrt_epi64(v128 a, bool promiseAbs = false, byte rangeLevelPr } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v256 mm256_cbrt_epi64(v256 a, bool promiseAbs = false, byte rangeLevelPromise = 0, byte elements = 4) + public static v256 mm256_cbrt_epi64(v256 a, bool promiseAbs = false, byte rangePromiseLevel = 0, byte elements = 4) { if (Avx2.IsAvx2Supported) { if (promiseAbs || constexpr.ALL_GE_EPI64(a, 0, elements)) { - return mm256_cbrt_epu64(a, rangeLevelPromise, elements); + return mm256_cbrt_epu64(a, rangePromiseLevel, elements); } else { v256 negative = mm256_srai_epi64(a, 63); - v256 cbrtAbs = mm256_cbrt_epu64(Avx2.mm256_xor_si256(Avx2.mm256_add_epi64(a, negative), negative), rangeLevelPromise, elements); + v256 cbrtAbs = mm256_cbrt_epu64(Avx2.mm256_xor_si256(Avx2.mm256_add_epi64(a, negative), negative), rangePromiseLevel, elements); return Avx2.mm256_xor_si256(Avx2.mm256_add_epi64(cbrtAbs, negative), negative); } @@ -2475,7 +2475,7 @@ public static uint2 intcbrt(uint2 x, Promise optimizations = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cbrt_epu32(RegisterConversion.ToV128(x), optimizations.CountUnsafeLevels(), 2)); + return RegisterConversion.ToUInt2(Xse.cbrt_epu32(RegisterConversion.ToV128(x), optimizations.CountUnsafeLevels(), 2)); } else { @@ -2493,7 +2493,7 @@ public static uint3 intcbrt(uint3 x, Promise optimizations = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cbrt_epu32(RegisterConversion.ToV128(x), optimizations.CountUnsafeLevels(), 3)); + return RegisterConversion.ToUInt3(Xse.cbrt_epu32(RegisterConversion.ToV128(x), optimizations.CountUnsafeLevels(), 3)); } else { @@ -2511,7 +2511,7 @@ public static uint4 intcbrt(uint4 x, Promise optimizations = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cbrt_epu32(RegisterConversion.ToV128(x), optimizations.CountUnsafeLevels(), 4)); + return RegisterConversion.ToUInt4(Xse.cbrt_epu32(RegisterConversion.ToV128(x), optimizations.CountUnsafeLevels(), 4)); } else { @@ -2572,7 +2572,7 @@ public static int2 intcbrt(int2 x, Promise optimizations = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cbrt_epi32(RegisterConversion.ToV128(x), optimizations.Promises(Promise.ZeroOrGreater), optimizations.CountUnsafeLevels(), 2)); + return RegisterConversion.ToInt2(Xse.cbrt_epi32(RegisterConversion.ToV128(x), optimizations.Promises(Promise.ZeroOrGreater), optimizations.CountUnsafeLevels(), 2)); } else { @@ -2591,7 +2591,7 @@ public static int3 intcbrt(int3 x, Promise optimizations = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cbrt_epi32(RegisterConversion.ToV128(x), optimizations.Promises(Promise.ZeroOrGreater), optimizations.CountUnsafeLevels(), 3)); + return RegisterConversion.ToInt3(Xse.cbrt_epi32(RegisterConversion.ToV128(x), optimizations.Promises(Promise.ZeroOrGreater), optimizations.CountUnsafeLevels(), 3)); } else { @@ -2610,7 +2610,7 @@ public static int4 intcbrt(int4 x, Promise optimizations = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cbrt_epi32(RegisterConversion.ToV128(x), optimizations.Promises(Promise.ZeroOrGreater), optimizations.CountUnsafeLevels(), 4)); + return RegisterConversion.ToInt4(Xse.cbrt_epi32(RegisterConversion.ToV128(x), optimizations.Promises(Promise.ZeroOrGreater), optimizations.CountUnsafeLevels(), 4)); } else { @@ -2847,7 +2847,7 @@ public static ulong intcbrt(ulong x, Promise optimizations = Promise.Nothing) /// Computes the componentwise integer cube root ⌊∛⌋ of a . /// - /// A '' with its flag set returns undefined results for input values outside the interval [0, 1ul << 40]. + /// A '' with its flag set returns undefined results for input values outside the interval [0, 1ul << 46]. /// A '' with its flag set returns undefined results for input values outside the interval [0, ]. /// A '' with its flag set returns undefined results for input values outside the interval [0, ]. /// A '' with its flag set returns undefined results for input values outside the interval [0, ]. @@ -2869,7 +2869,7 @@ public static ulong2 intcbrt(ulong2 x, Promise optimizations = Promise.Nothing) /// Computes the componentwise integer cube root ⌊∛⌋ of a . /// - /// A '' with its flag set returns undefined results for input values outside the interval [0, 1ul << 40]. + /// A '' with its flag set returns undefined results for input values outside the interval [0, 1ul << 46]. /// A '' with its flag set returns undefined results for input values outside the interval [0, ]. /// A '' with its flag set returns undefined results for input values outside the interval [0, ]. /// A '' with its flag set returns undefined results for input values outside the interval [0, ]. @@ -2895,7 +2895,7 @@ public static ulong3 intcbrt(ulong3 x, Promise optimizations = Promise.Nothing) /// Computes the componentwise integer cube root ⌊∛⌋ of a . /// - /// A '' with its flag set returns undefined results for input values outside the interval [0, 1ul << 40]. + /// A '' with its flag set returns undefined results for input values outside the interval [0, 1ul << 46]. /// A '' with its flag set returns undefined results for input values outside the interval [0, ]. /// A '' with its flag set returns undefined results for input values outside the interval [0, ]. /// A '' with its flag set returns undefined results for input values outside the interval [0, ]. @@ -2941,7 +2941,7 @@ public static long intcbrt(long x, Promise optimizations = Promise.Nothing) /// Computes the componentwise integer cube root sgn() * ⌊|∛|⌋ of a . /// /// A '' with its flag set returns undefined results for negative input values. - /// A '' with its flag set returns undefined results for input values outside the interval [0, 1ul << 40] if the flag is also set, [-(1ul << 40), 1ul << 40] otherwise. + /// A '' with its flag set returns undefined results for input values outside the interval [0, 1ul << 46] if the flag is also set, [-(1ul << 46), 1ul << 46] otherwise. /// A '' with its flag set returns undefined results for input values outside the interval [0, ] if the flag is also set, [-, ] otherwise. /// A '' with its flag set returns undefined results for input values outside the interval [0, ] if the flag is also set, [-, ] otherwise. /// A '' with its flag set returns undefined results for input values outside the interval [0, ] if the flag is also set, [-, ] otherwise. @@ -2964,7 +2964,7 @@ public static long2 intcbrt(long2 x, Promise optimizations = Promise.Nothing) /// Computes the componentwise integer cube root sgn() * ⌊|∛|⌋ of a . /// /// A '' with its flag set returns undefined results for negative input values. - /// A '' with its flag set returns undefined results for input values outside the interval [0, 1ul << 40] if the flag is also set, [-(1ul << 40), 1ul << 40] otherwise. + /// A '' with its flag set returns undefined results for input values outside the interval [0, 1ul << 46] if the flag is also set, [-(1ul << 46), 1ul << 46] otherwise. /// A '' with its flag set returns undefined results for input values outside the interval [0, ] if the flag is also set, [-, ] otherwise. /// A '' with its flag set returns undefined results for input values outside the interval [0, ] if the flag is also set, [-, ] otherwise. /// A '' with its flag set returns undefined results for input values outside the interval [0, ] if the flag is also set, [-, ] otherwise. @@ -2991,7 +2991,7 @@ public static long3 intcbrt(long3 x, Promise optimizations = Promise.Nothing) /// Computes the componentwise integer cube root sgn() * ⌊|∛|⌋ of a . /// /// A '' with its flag set returns undefined results for negative input values. - /// A '' with its flag set returns undefined results for input values outside the interval [0, 1ul << 40] if the flag is also set, [-(1ul << 40), 1ul << 40] otherwise. + /// A '' with its flag set returns undefined results for input values outside the interval [0, 1ul << 46] if the flag is also set, [-(1ul << 46), 1ul << 46] otherwise. /// A '' with its flag set returns undefined results for input values outside the interval [0, ] if the flag is also set, [-, ] otherwise. /// A '' with its flag set returns undefined results for input values outside the interval [0, ] if the flag is also set, [-, ] otherwise. /// A '' with its flag set returns undefined results for input values outside the interval [0, ] if the flag is also set, [-, ] otherwise. diff --git a/Runtime/Math Lib/Functions/Arithmetic/Integer/Exponentiation.cs b/Runtime/Math Lib/Functions/Arithmetic/Integer/Exponentiation.cs index 7a96155..40cecd9 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Integer/Exponentiation.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Integer/Exponentiation.cs @@ -1281,7 +1281,7 @@ public static int2 intpow(int2 x, uint2 n) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.pow_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), 2)); + return RegisterConversion.ToInt2(Xse.pow_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), 2)); } else { @@ -1295,7 +1295,7 @@ public static int3 intpow(int3 x, uint3 n) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.pow_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), 3)); + return RegisterConversion.ToInt3(Xse.pow_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), 3)); } else { @@ -1310,7 +1310,7 @@ public static int4 intpow(int4 x, uint4 n) if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.pow_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), 4)); + return RegisterConversion.ToInt4(Xse.pow_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Integer/Factorial.cs b/Runtime/Math Lib/Functions/Arithmetic/Integer/Factorial.cs index 1427e9a..07b1b64 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Integer/Factorial.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Integer/Factorial.cs @@ -5,6 +5,7 @@ using MaxMath.Intrinsics; using static Unity.Burst.Intrinsics.X86; +using static MaxMath.LUT.FACTORIAL; namespace MaxMath { @@ -14,6 +15,7 @@ unsafe public static partial class Xse { private static v128 FACTORIALS_EPU8 { + [MethodImpl(MethodImplOptions.AggressiveInlining)] get { if (Sse2.IsSse2Supported) @@ -24,16 +26,43 @@ private static v128 FACTORIALS_EPU8 } } - + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v128 gamma_epu16_epu8range(v128 a) + { + if (Ssse3.IsSsse3Supported) + { + a = Sse2.or_si128(a, Sse2.set1_epi16(unchecked((short)0xFF00))); + + return Ssse3.shuffle_epi8(FACTORIALS_EPU8, a); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v256 mm256_gamma_epu16_epu8range(v256 a) + { + if (Avx2.IsAvx2Supported) + { + a = Avx2.mm256_or_si256(a, Avx.mm256_set1_epi16(unchecked((short)0xFF00))); + + return Avx2.mm256_shuffle_epi8(new v256(FACTORIALS_EPU8, FACTORIALS_EPU8), a); + } + else throw new IllegalInstructionException(); + } + + [SkipLocalsInit] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v128 gamma_epu8(v128 a, bool promiseNoOverflow = false, byte elements = 16) { + promiseNoOverflow |= constexpr.ALL_LE_EPU8(a, MAX_INVERSE_FACTORIAL_U8, elements); + if (Ssse3.IsSsse3Supported) { if (!promiseNoOverflow) { - a = Sse2.min_epu8(a, Sse2.set1_epi8(7)); + a = Sse2.min_epu8(a, Sse2.set1_epi8(MAX_INVERSE_FACTORIAL_U8 + 1)); } return Ssse3.shuffle_epi8(FACTORIALS_EPU8, a); @@ -82,9 +111,11 @@ public static v256 mm256_gamma_epu8(v256 a, bool promiseNoOverflow = false) { if (Avx2.IsAvx2Supported) { + promiseNoOverflow |= constexpr.ALL_LE_EPU8(a, MAX_INVERSE_FACTORIAL_U8); + if (!promiseNoOverflow) { - a = Avx2.mm256_min_epu8(a, Avx.mm256_set1_epi8(7)); + a = Avx2.mm256_min_epu8(a, Avx.mm256_set1_epi8(MAX_INVERSE_FACTORIAL_U8 + 1)); } return Avx2.mm256_shuffle_epi8(new v256(FACTORIALS_EPU8, FACTORIALS_EPU8), a); @@ -97,13 +128,13 @@ public static v256 mm256_gamma_epu8(v256 a, bool promiseNoOverflow = false) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v128 gamma_epu16(v128 a, bool promiseNoOverflow = false, byte elements = 8) { + promiseNoOverflow |= constexpr.ALL_LE_EPU16(a, MAX_INVERSE_FACTORIAL_U16, elements); + if (Ssse3.IsSsse3Supported) { - if (constexpr.ALL_LE_EPU16(a, 5)) + if (constexpr.ALL_LE_EPU16(a, MAX_INVERSE_FACTORIAL_U8, elements)) { - a = Sse2.or_si128(a, Sse2.set1_epi16(unchecked((short)0xFF00))); - - return Ssse3.shuffle_epi8(FACTORIALS_EPU8, a); + return gamma_epu16_epu8range(a); } } @@ -111,7 +142,7 @@ public static v128 gamma_epu16(v128 a, bool promiseNoOverflow = false, byte elem { if (!promiseNoOverflow) { - a = min_epu16(a, Sse2.set1_epi16(9)); + a = min_epu16(a, Sse2.set1_epi16(MAX_INVERSE_FACTORIAL_U16 + 1)); } if (Avx2.IsAvx2Supported) @@ -159,18 +190,18 @@ public static v128 gamma_epu16(v128 a, bool promiseNoOverflow = false, byte elem [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v256 mm256_gamma_epu16(v256 a, bool promiseNoOverflow = false) { + promiseNoOverflow |= constexpr.ALL_LE_EPU16(a, MAX_INVERSE_FACTORIAL_U16); + if (Avx2.IsAvx2Supported) { - if (constexpr.ALL_LE_EPU16(a, 5)) + if (constexpr.ALL_LE_EPU16(a, MAX_INVERSE_FACTORIAL_U8)) { - a = Avx2.mm256_or_si256(a, Avx.mm256_set1_epi16(unchecked((short)0xFF00))); - - return Avx2.mm256_shuffle_epi8(new v256(FACTORIALS_EPU8, FACTORIALS_EPU8), a); + return mm256_gamma_epu16_epu8range(a); } if (!promiseNoOverflow) { - a = Avx2.mm256_min_epu16(a, Avx.mm256_set1_epi16(9)); + a = Avx2.mm256_min_epu16(a, Avx.mm256_set1_epi16(MAX_INVERSE_FACTORIAL_U16 + 1)); } uint* TABLE = stackalloc uint[10] { 1, 1, 2, 6, 24, 120, 720, 5_040, 40_320, ushort.MaxValue }; @@ -190,9 +221,11 @@ public static v256 mm256_gamma_epu16(v256 a, bool promiseNoOverflow = false) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v128 gamma_epi16(v128 a, bool promiseNoOverflow = false, byte elements = 8) { + promiseNoOverflow |= constexpr.ALL_LE_EPI16(a, MAX_INVERSE_FACTORIAL_S16); + if (Ssse3.IsSsse3Supported) { - if (constexpr.ALL_LE_EPU16(a, 5)) + if (constexpr.ALL_LE_EPU16(a, MAX_INVERSE_FACTORIAL_U8, elements)) { a = Sse2.or_si128(a, Sse2.set1_epi16(unchecked((short)0xFF00))); @@ -204,7 +237,7 @@ public static v128 gamma_epi16(v128 a, bool promiseNoOverflow = false, byte elem { if (!promiseNoOverflow) { - a = min_epu16(a, Sse2.set1_epi16(8)); + a = min_epu16(a, Sse2.set1_epi16(MAX_INVERSE_FACTORIAL_S16 + 1)); } if (Avx2.IsAvx2Supported) @@ -252,9 +285,11 @@ public static v128 gamma_epi16(v128 a, bool promiseNoOverflow = false, byte elem [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v256 mm256_gamma_epi16(v256 a, bool promiseNoOverflow = false) { + promiseNoOverflow |= constexpr.ALL_LE_EPI16(a, MAX_INVERSE_FACTORIAL_S16); + if (Avx2.IsAvx2Supported) { - if (constexpr.ALL_LE_EPU16(a, 5)) + if (constexpr.ALL_LE_EPU16(a, MAX_INVERSE_FACTORIAL_U8)) { a = Avx2.mm256_or_si256(a, Avx.mm256_set1_epi16(unchecked((short)0xFF00))); @@ -263,7 +298,7 @@ public static v256 mm256_gamma_epi16(v256 a, bool promiseNoOverflow = false) if (!promiseNoOverflow) { - a = Avx2.mm256_min_epu16(a, Avx.mm256_set1_epi16(9)); + a = Avx2.mm256_min_epu16(a, Avx.mm256_set1_epi16(MAX_INVERSE_FACTORIAL_S16 + 1)); } uint* TABLE = stackalloc uint[9] { 1, 1, 2, 6, 24, 120, 720, 5_040, (uint)short.MaxValue }; @@ -283,9 +318,11 @@ public static v256 mm256_gamma_epi16(v256 a, bool promiseNoOverflow = false) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v128 gamma_epu32(v128 a, bool promiseNoOverflow = false, byte elements = 4) { + promiseNoOverflow |= constexpr.ALL_LE_EPU32(a, MAX_INVERSE_FACTORIAL_U32, elements); + if (Ssse3.IsSsse3Supported) { - if (constexpr.ALL_LE_EPU32(a, 5)) + if (constexpr.ALL_LE_EPU32(a, MAX_INVERSE_FACTORIAL_U8)) { a = Sse2.or_si128(a, Sse2.set1_epi32(unchecked((int)0xFFFF_FF00u))); @@ -297,7 +334,7 @@ public static v128 gamma_epu32(v128 a, bool promiseNoOverflow = false, byte elem { if (!promiseNoOverflow) { - a = min_epu32(a, Sse2.set1_epi32(13)); + a = min_epu32(a, Sse2.set1_epi32(MAX_INVERSE_FACTORIAL_U32 + 1)); } uint* TABLE = stackalloc uint[14] { 1, 1, 2, 6, 24, 120, 720, 5_040, 40_320, 362_880, 3_628_800, 39_916_800, 479_001_600, uint.MaxValue }; @@ -325,9 +362,11 @@ public static v128 gamma_epu32(v128 a, bool promiseNoOverflow = false, byte elem [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v256 mm256_gamma_epu32(v256 a, bool promiseNoOverflow = false) { + promiseNoOverflow |= constexpr.ALL_LE_EPU32(a, MAX_INVERSE_FACTORIAL_U32); + if (Avx2.IsAvx2Supported) { - if (constexpr.ALL_LE_EPU32(a, 5)) + if (constexpr.ALL_LE_EPU32(a, MAX_INVERSE_FACTORIAL_U8)) { a = Avx2.mm256_or_si256(a, Avx.mm256_set1_epi32(unchecked((int)0xFFFF_FF00u))); @@ -336,7 +375,7 @@ public static v256 mm256_gamma_epu32(v256 a, bool promiseNoOverflow = false) if (!promiseNoOverflow) { - a = Avx2.mm256_min_epu32(a, Avx.mm256_set1_epi32(13)); + a = Avx2.mm256_min_epu32(a, Avx.mm256_set1_epi32(MAX_INVERSE_FACTORIAL_U32 + 1)); } uint* TABLE = stackalloc uint[14] { 1, 1, 2, 6, 24, 120, 720, 5_040, 40_320, 362_880, 3_628_800, 39_916_800, 479_001_600, uint.MaxValue }; @@ -351,9 +390,11 @@ public static v256 mm256_gamma_epu32(v256 a, bool promiseNoOverflow = false) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v128 gamma_epu64(v128 a, bool promiseNoOverflow = false) { + promiseNoOverflow |= constexpr.ALL_LE_EPU64(a, MAX_INVERSE_FACTORIAL_U64); + if (Ssse3.IsSsse3Supported) { - if (constexpr.ALL_LE_EPU64(a, 5)) + if (constexpr.ALL_LE_EPU64(a, MAX_INVERSE_FACTORIAL_U8)) { a = Sse2.or_si128(a, Sse2.set1_epi64x(unchecked((long)0xFFFF_FFFF_FFFF_FF00ul))); @@ -365,7 +406,7 @@ public static v128 gamma_epu64(v128 a, bool promiseNoOverflow = false) { if (!promiseNoOverflow) { - a = min_epu64(a, Sse2.set1_epi64x(21)); + a = min_epu64(a, Sse2.set1_epi64x(MAX_INVERSE_FACTORIAL_U64 + 1)); } ulong* TABLE = stackalloc ulong[22] { 1, 1, 2, 6, 24, 120, 720, 5_040, 40_320, 362_880, 3_628_800, 39_916_800, 479_001_600, 6_227_020_800ul, 87_178_291_200ul, 1_307_674_368_000ul, 20_922_789_888_000ul, 355_687_428_096_000ul, 6_402_373_705_728_000ul, 121_645_100_408_832_000ul, 2_432_902_008_176_640_000ul, ulong.MaxValue }; @@ -388,75 +429,11 @@ public static v128 gamma_epu64(v128 a, bool promiseNoOverflow = false) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v256 mm256_gamma_epu64(v256 a, bool promiseNoOverflow = false, byte elements = 4) { - if (Avx2.IsAvx2Supported) - { - if (constexpr.ALL_LE_EPU32(a, 5)) - { - a = Avx2.mm256_or_si256(a, Avx.mm256_set1_epi64x(unchecked((long)0xFFFF_FFFF_FFFF_FF00ul))); - - return Avx2.mm256_shuffle_epi8(new v256(FACTORIALS_EPU8, FACTORIALS_EPU8), a); - } - - if (!promiseNoOverflow) - { - a = mm256_min_epu64(a, Avx.mm256_set1_epi64x(21)); - } - else if (elements == 3) - { - a.SLong3 = 0; - } - - ulong* TABLE = stackalloc ulong[22] { 1, 1, 2, 6, 24, 120, 720, 5_040, 40_320, 362_880, 3_628_800, 39_916_800, 479_001_600, 6_227_020_800ul, 87_178_291_200ul, 1_307_674_368_000ul, 20_922_789_888_000ul, 355_687_428_096_000ul, 6_402_373_705_728_000ul, 121_645_100_408_832_000ul, 2_432_902_008_176_640_000ul, ulong.MaxValue }; - - return Avx2.mm256_i64gather_epi64(TABLE, a, sizeof(ulong)); - } - else throw new IllegalInstructionException(); - } - - [SkipLocalsInit] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v128 gamma_epi64(v128 a, bool promiseNoOverflow = false) - { - if (Ssse3.IsSsse3Supported) - { - if (constexpr.ALL_LE_EPU64(a, 5)) - { - a = Sse2.or_si128(a, Sse2.set1_epi64x(unchecked((long)0xFFFF_FFFF_FFFF_FF00ul))); - - return Ssse3.shuffle_epi8(FACTORIALS_EPU8, a); - } - } - - if (Sse2.IsSse2Supported) - { - if (!promiseNoOverflow) - { - a = min_epu64(a, Sse2.set1_epi64x(21)); - } - - long* TABLE = stackalloc long[22] { 1, 1, 2, 6, 24, 120, 720, 5_040, 40_320, 362_880, 3_628_800, 39_916_800, 479_001_600, 6_227_020_800L, 87_178_291_200L, 1_307_674_368_000L, 20_922_789_888_000L, 355_687_428_096_000L, 6_402_373_705_728_000L, 121_645_100_408_832_000L, 2_432_902_008_176_640_000L, long.MaxValue }; - - if (Avx2.IsAvx2Supported) - { - return Avx2.i64gather_epi64(TABLE, a, sizeof(ulong)); - } - else - { - a = Sse2.slli_epi64(a, 3); + promiseNoOverflow |= constexpr.ALL_LE_EPU64(a, MAX_INVERSE_FACTORIAL_U64, elements); - return new v128(*(ulong*)((byte*)TABLE + a.ULong0), *(ulong*)((byte*)TABLE + a.ULong1)); - } - } - else throw new IllegalInstructionException(); - } - - [SkipLocalsInit] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v256 mm256_gamma_epi64(v256 a, bool promiseNoOverflow = false, byte elements = 4) - { if (Avx2.IsAvx2Supported) { - if (constexpr.ALL_LE_EPU32(a, 5)) + if (constexpr.ALL_LE_EPU64(a, MAX_INVERSE_FACTORIAL_U8, elements)) { a = Avx2.mm256_or_si256(a, Avx.mm256_set1_epi64x(unchecked((long)0xFFFF_FFFF_FFFF_FF00ul))); @@ -465,14 +442,14 @@ public static v256 mm256_gamma_epi64(v256 a, bool promiseNoOverflow = false, byt if (!promiseNoOverflow) { - a = mm256_min_epu64(a, Avx.mm256_set1_epi64x(21)); + a = mm256_min_epu64(a, Avx.mm256_set1_epi64x(MAX_INVERSE_FACTORIAL_U64 + 1), elements); } else if (elements == 3) { a.SLong3 = 0; } - long* TABLE = stackalloc long[22] { 1, 1, 2, 6, 24, 120, 720, 5_040, 40_320, 362_880, 3_628_800, 39_916_800, 479_001_600, 6_227_020_800L, 87_178_291_200L, 1_307_674_368_000L, 20_922_789_888_000L, 355_687_428_096_000L, 6_402_373_705_728_000L, 121_645_100_408_832_000L, 2_432_902_008_176_640_000L, long.MaxValue }; + ulong* TABLE = stackalloc ulong[22] { 1, 1, 2, 6, 24, 120, 720, 5_040, 40_320, 362_880, 3_628_800, 39_916_800, 479_001_600, 6_227_020_800ul, 87_178_291_200ul, 1_307_674_368_000ul, 20_922_789_888_000ul, 355_687_428_096_000ul, 6_402_373_705_728_000ul, 121_645_100_408_832_000ul, 2_432_902_008_176_640_000ul, ulong.MaxValue }; return Avx2.mm256_i64gather_epi64(TABLE, a, sizeof(ulong)); } @@ -490,12 +467,12 @@ unsafe public static partial class maxmath [MethodImpl(MethodImplOptions.AggressiveInlining)] public static UInt128 factorial(UInt128 x, Promise noOverflow = Promise.Nothing) { - if (Xse.constexpr.IS_TRUE(x <= 20)) + if (Xse.constexpr.IS_TRUE(x <= MAX_INVERSE_FACTORIAL_U64)) { return factorial(x.lo64, Promise.NoOverflow); } - if (Xse.constexpr.IS_TRUE(x < 35)) + if (Xse.constexpr.IS_TRUE(x <= MAX_INVERSE_FACTORIAL_U128)) { noOverflow |= Promise.NoOverflow; } @@ -553,12 +530,12 @@ public static UInt128 factorial(UInt128 x, Promise noOverflow = Promise.Nothing) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Int128 factorial(Int128 x, Promise noOverflow = Promise.Nothing) { - if (Xse.constexpr.IS_TRUE(x >= 0 & x <= 33)) + if (Xse.constexpr.IS_TRUE(x >= 0 & x <= MAX_INVERSE_FACTORIAL_S128)) { noOverflow |= Promise.NoOverflow; } - if (Xse.constexpr.IS_TRUE(x <= 20)) + if (Xse.constexpr.IS_TRUE(x <= MAX_INVERSE_FACTORIAL_U64)) { if (Xse.constexpr.IS_TRUE(x >= 0)) { @@ -593,19 +570,19 @@ public static Int128 factorial(Int128 x, Promise noOverflow = Promise.Nothing) 6_402_373_705_728_000ul, 121_645_100_408_832_000ul, 2_432_902_008_176_640_000ul, - /*51090942171709440000*/new Int128(0xC507_7D36_B8C4_0000, 0x0000_0000_0000_0002), - /*1124000727777607680000*/new Int128(0xEEA4_C2B3_E0D8_0000, 0x0000_0000_0000_003C), - /*25852016738884976640000*/new Int128(0x70CD_7E29_3368_0000, 0x0000_0000_0000_0579), - /*620448401733239439360000*/new Int128(0x9343_D3DC_D1C0_0000, 0x0000_0000_0000_8362), - /*15511210043330985984000000*/new Int128(0x619F_B090_7BC0_0000, 0x0000_0000_000C_D4A0), - /*403291461126605635584000000*/new Int128(0xEA37_EEAC_9180_0000, 0x0000_0000_014D_9849), - /*10888869450418352160768000000*/new Int128(0xB3E6_2C33_5880_0000, 0x0000_0000_232F_0FCB), - /*304888344611713860501504000000*/new Int128(0xAD2C_D59D_AE00_0000, 0x0000_0003_D925_BA47), - /*8841761993739701954543616000000*/new Int128(0x9E14_32DC_B600_0000, 0x0000_006F_9946_1A1E), - /*265252859812191058636308480000000*/new Int128(0x865D_F5DD_5400_0000, 0x0000_0D13_F637_0F96), - /*8222838654177922817725562880000000*/new Int128(0x4560_C5CD_2C00_0000, 0x0001_956A_D0AA_E33A), - /*263130836933693530167218012160000000*/new Int128(0xAC18_B9A5_8000_0000, 0x0032_AD5A_155C_6748), - /*8683317618811886495518194401280000000*/new Int128(0x2F2F_EE55_8000_0000, 0x0688_589C_C0E9_505E), + /*51_090_942_171_709_440_000*/new Int128(0xC507_7D36_B8C4_0000, 0x0000_0000_0000_0002), + /*1_124_000_727_777_607_680_000*/new Int128(0xEEA4_C2B3_E0D8_0000, 0x0000_0000_0000_003C), + /*25_852_016_738_884_976_640_000*/new Int128(0x70CD_7E29_3368_0000, 0x0000_0000_0000_0579), + /*620_448_401_733_239_439_360_000*/new Int128(0x9343_D3DC_D1C0_0000, 0x0000_0000_0000_8362), + /*15_511_210_043_330_985_984_000_000*/new Int128(0x619F_B090_7BC0_0000, 0x0000_0000_000C_D4A0), + /*403_291_461_126_605_635_584_000_000*/new Int128(0xEA37_EEAC_9180_0000, 0x0000_0000_014D_9849), + /*10_888_869_450_418_352_160_768_000_000*/new Int128(0xB3E6_2C33_5880_0000, 0x0000_0000_232F_0FCB), + /*304_888_344_611_713_860_501_504_000_000*/new Int128(0xAD2C_D59D_AE00_0000, 0x0000_0003_D925_BA47), + /*8_841_761_993_739_701_954_543_616_000_000*/new Int128(0x9E14_32DC_B600_0000, 0x0000_006F_9946_1A1E), + /*265_252_859_812_191_058_636_308_480_000_000*/new Int128(0x865D_F5DD_5400_0000, 0x0000_0D13_F637_0F96), + /*8_222_838_654_177_922_817_725_562_880_000_000*/new Int128(0x4560_C5CD_2C00_0000, 0x0001_956A_D0AA_E33A), + /*263_130_836_933_693_530_167_218_012_160_000_000*/new Int128(0xAC18_B9A5_8000_0000, 0x0032_AD5A_155C_6748), + /*8_683_317_618_811_886_495_518_194_401_280_000_000*/new Int128(0x2F2F_EE55_8000_0000, 0x0688_589C_C0E9_505E), Int128.MaxValue }; @@ -622,7 +599,7 @@ public static Int128 factorial(Int128 x, Promise noOverflow = Promise.Nothing) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte factorial(byte x, Promise noOverflow = Promise.Nothing) { - if (Xse.constexpr.IS_TRUE(x < 6)) + if (Xse.constexpr.IS_TRUE(x <= MAX_INVERSE_FACTORIAL_U8)) { noOverflow |= Promise.NoOverflow; } @@ -732,7 +709,7 @@ public static byte32 factorial(byte32 x, Promise noOverflow = Promise.Nothing) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte factorial(sbyte x, Promise noOverflow = Promise.Nothing) { - if (Xse.constexpr.IS_TRUE(x >= 0 & x <= 5)) + if (Xse.constexpr.IS_TRUE(x >= 0 & x <= MAX_INVERSE_FACTORIAL_S8)) { noOverflow |= Promise.NoOverflow; } @@ -844,12 +821,12 @@ public static sbyte32 factorial(sbyte32 x, Promise noOverflow = Promise.Nothing) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort factorial(ushort x, Promise noOverflow = Promise.Nothing) { - if (Xse.constexpr.IS_TRUE(x <= 5)) + if (Xse.constexpr.IS_TRUE(x <= MAX_INVERSE_FACTORIAL_U8)) { return factorial((byte)x, Promise.NoOverflow); } - if (Xse.constexpr.IS_TRUE(x < 9)) + if (Xse.constexpr.IS_TRUE(x <= MAX_INVERSE_FACTORIAL_U16)) { noOverflow |= Promise.NoOverflow; } @@ -945,12 +922,12 @@ public static ushort16 factorial(ushort16 x, Promise noOverflow = Promise.Nothin [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short factorial(short x, Promise noOverflow = Promise.Nothing) { - if (Xse.constexpr.IS_TRUE(x >= 0 & x <= 7)) + if (Xse.constexpr.IS_TRUE(x >= 0 & x <= MAX_INVERSE_FACTORIAL_S16)) { noOverflow |= Promise.NoOverflow; } - if (Xse.constexpr.IS_TRUE(x <= 5)) + if (Xse.constexpr.IS_TRUE(x <= MAX_INVERSE_FACTORIAL_U8)) { return factorial((byte)x, noOverflow); } @@ -1046,12 +1023,12 @@ public static short16 factorial(short16 x, Promise noOverflow = Promise.Nothing) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint factorial(uint x, Promise noOverflow = Promise.Nothing) { - if (Xse.constexpr.IS_TRUE(x <= 7)) + if (Xse.constexpr.IS_TRUE(x <= MAX_INVERSE_FACTORIAL_U16)) { return factorial((ushort)x, Promise.NoOverflow); } - if (Xse.constexpr.IS_TRUE(x < 13)) + if (Xse.constexpr.IS_TRUE(x <= MAX_INVERSE_FACTORIAL_U32)) { noOverflow |= Promise.NoOverflow; } @@ -1072,7 +1049,7 @@ public static uint2 factorial(uint2 x, Promise noOverflow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.gamma_epu32(RegisterConversion.ToV128(x), noOverflow.Promises(Promise.NoOverflow), 2)); + return RegisterConversion.ToUInt2(Xse.gamma_epu32(RegisterConversion.ToV128(x), noOverflow.Promises(Promise.NoOverflow), 2)); } else { @@ -1087,7 +1064,7 @@ public static uint3 factorial(uint3 x, Promise noOverflow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.gamma_epu32(RegisterConversion.ToV128(x), noOverflow.Promises(Promise.NoOverflow), 3)); + return RegisterConversion.ToUInt3(Xse.gamma_epu32(RegisterConversion.ToV128(x), noOverflow.Promises(Promise.NoOverflow), 3)); } else { @@ -1102,7 +1079,7 @@ public static uint4 factorial(uint4 x, Promise noOverflow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.gamma_epu32(RegisterConversion.ToV128(x), noOverflow.Promises(Promise.NoOverflow), 4)); + return RegisterConversion.ToUInt4(Xse.gamma_epu32(RegisterConversion.ToV128(x), noOverflow.Promises(Promise.NoOverflow), 4)); } else { @@ -1132,18 +1109,18 @@ public static uint8 factorial(uint8 x, Promise noOverflow = Promise.Nothing) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int factorial(int x, Promise noOverflow = Promise.Nothing) { - if (Xse.constexpr.IS_TRUE(x >= 0 & x <= 12)) + if (Xse.constexpr.IS_TRUE(x >= 0 & x <= MAX_INVERSE_FACTORIAL_S32)) { noOverflow |= Promise.NoOverflow; } - if (Xse.constexpr.IS_TRUE(x <= 8)) + if (Xse.constexpr.IS_TRUE(x <= MAX_INVERSE_FACTORIAL_U16)) { if (Xse.constexpr.IS_TRUE(x >= 0)) { return factorial((ushort)x, Promise.NoOverflow); } - if (Xse.constexpr.IS_TRUE(x <= 7)) + if (Xse.constexpr.IS_TRUE(x <= MAX_INVERSE_FACTORIAL_S16)) { return factorial((short)x, noOverflow); } @@ -1165,7 +1142,7 @@ public static int2 factorial(int2 x, Promise noOverflow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.gamma_epu32(RegisterConversion.ToV128(x), noOverflow.Promises(Promise.NoOverflow), 2)); + return RegisterConversion.ToInt2(Xse.gamma_epu32(RegisterConversion.ToV128(x), noOverflow.Promises(Promise.NoOverflow), 2)); } else { @@ -1180,7 +1157,7 @@ public static int3 factorial(int3 x, Promise noOverflow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.gamma_epu32(RegisterConversion.ToV128(x), noOverflow.Promises(Promise.NoOverflow), 3)); + return RegisterConversion.ToInt3(Xse.gamma_epu32(RegisterConversion.ToV128(x), noOverflow.Promises(Promise.NoOverflow), 3)); } else { @@ -1195,7 +1172,7 @@ public static int4 factorial(int4 x, Promise noOverflow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.gamma_epu32(RegisterConversion.ToV128(x), noOverflow.Promises(Promise.NoOverflow), 4)); + return RegisterConversion.ToInt4(Xse.gamma_epu32(RegisterConversion.ToV128(x), noOverflow.Promises(Promise.NoOverflow), 4)); } else { @@ -1225,12 +1202,12 @@ public static int8 factorial(int8 x, Promise noOverflow = Promise.Nothing) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong factorial(ulong x, Promise noOverflow = Promise.Nothing) { - if (Xse.constexpr.IS_TRUE(x <= 12)) + if (Xse.constexpr.IS_TRUE(x <= MAX_INVERSE_FACTORIAL_U32)) { return factorial((uint)x, Promise.NoOverflow); } - if (Xse.constexpr.IS_TRUE(x < 21)) + if (Xse.constexpr.IS_TRUE(x <= MAX_INVERSE_FACTORIAL_U64)) { noOverflow |= Promise.NoOverflow; } @@ -1296,12 +1273,12 @@ public static ulong4 factorial(ulong4 x, Promise noOverflow = Promise.Nothing) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long factorial(long x, Promise noOverflow = Promise.Nothing) { - if (Xse.constexpr.IS_TRUE(x >= 0 & x <= 20)) + if (Xse.constexpr.IS_TRUE(x >= 0 & x <= MAX_INVERSE_FACTORIAL_U64)) { noOverflow |= Promise.NoOverflow; } - if (Xse.constexpr.IS_TRUE(x <= 12)) + if (Xse.constexpr.IS_TRUE(x <= MAX_INVERSE_FACTORIAL_U32)) { if (Xse.constexpr.IS_TRUE(x >= 0)) { @@ -1329,7 +1306,7 @@ public static long2 factorial(long2 x, Promise noOverflow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return Xse.gamma_epi64(x, noOverflow.Promises(Promise.NoOverflow)); + return Xse.gamma_epu64(x, noOverflow.Promises(Promise.NoOverflow)); } else { @@ -1344,7 +1321,7 @@ public static long3 factorial(long3 x, Promise noOverflow = Promise.Nothing) { if (Avx2.IsAvx2Supported) { - return Xse.mm256_gamma_epi64(x, noOverflow.Promises(Promise.NoOverflow), 3); + return Xse.mm256_gamma_epu64(x, noOverflow.Promises(Promise.NoOverflow), 3); } else { @@ -1359,7 +1336,7 @@ public static long4 factorial(long4 x, Promise noOverflow = Promise.Nothing) { if (Avx2.IsAvx2Supported) { - return Xse.mm256_gamma_epi64(x, noOverflow.Promises(Promise.NoOverflow), 4); + return Xse.mm256_gamma_epu64(x, noOverflow.Promises(Promise.NoOverflow), 4); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Integer/Greatest Common Divisor.cs b/Runtime/Math Lib/Functions/Arithmetic/Integer/Greatest Common Divisor.cs index 0dea9cb..38f962a 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Integer/Greatest Common Divisor.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Integer/Greatest Common Divisor.cs @@ -834,7 +834,7 @@ public static uint2 gcd(uint2 x, uint2 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.gcd_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 2)); + return RegisterConversion.ToUInt2(Xse.gcd_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 2)); } else { @@ -848,7 +848,7 @@ public static uint3 gcd(uint3 x, uint3 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.gcd_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 3)); + return RegisterConversion.ToUInt3(Xse.gcd_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 3)); } else { @@ -862,7 +862,7 @@ public static uint4 gcd(uint4 x, uint4 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.gcd_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 4)); + return RegisterConversion.ToUInt4(Xse.gcd_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Integer/Least Common Multiple.cs b/Runtime/Math Lib/Functions/Arithmetic/Integer/Least Common Multiple.cs index 9670d07..33eaf01 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Integer/Least Common Multiple.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Integer/Least Common Multiple.cs @@ -2,9 +2,231 @@ using Unity.Mathematics; using Unity.Burst.CompilerServices; using MaxMath.Intrinsics; +using Unity.Burst.Intrinsics; + +using static Unity.Burst.Intrinsics.X86; namespace MaxMath { + namespace Intrinsics + { + unsafe public static partial class Xse + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 lcm_epu8(v128 a, v128 b, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + switch (elements) + { + case 2: + case 3: + case 4: + { + v128 left; + if (Constant.IsConstantExpression(a)) + { + left = cvtepu8_ps(b); // counter-intuitive but this is free (ILP during gcd); whereas multiplication at the very end could be up to 4 cycles faster this way + } + else + { + left = cvtepu8_ps(a); + } + + v128 right = cvtepu8_ps(gcd_epu8(a, b)); + v128 ints = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(left, right); + + if (Sse4_1.IsSse41Supported) + { + if (Constant.IsConstantExpression(a)) + { + return cvtepi32_epi8(Sse4_1.mullo_epi32(ints, a), elements); + } + else + { + return cvtepi32_epi8(Sse4_1.mullo_epi32(ints, b), elements); + } + } + else + { + if (Constant.IsConstantExpression(a)) + { + return cvtepi16_epi8(Sse2.mullo_epi16(Sse2.packs_epi32(ints, ints), a), elements); + } + else + { + return cvtepi16_epi8(Sse2.mullo_epi16(Sse2.packs_epi32(ints, ints), b), elements); + } + } + } + case 8: + { + v128 leftLo; + v128 leftHi; + if (Constant.IsConstantExpression(a)) + { + leftLo = cvt2x2epu16_ps(cvtepu8_epi16(b), out leftHi); // counter-intuitive but this is free (ILP during gcd); whereas multiplication at the very end could be up to 4 cycles faster this way + } + else + { + leftLo = cvt2x2epu16_ps(cvtepu8_epi16(a), out leftHi); + } + + v128 rightLo = cvt2x2epu16_ps(cvtepu8_epi16(gcd_epu8(a, b)), out v128 rightHi); + + v128 intsLo = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftLo, rightLo); + v128 intsHi = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftHi, rightHi); + + if (Constant.IsConstantExpression(a)) + { + return cvtepi16_epi8(Sse2.mullo_epi16(Sse2.packs_epi32(intsLo, intsHi), a), 8); + } + else + { + return cvtepi16_epi8(Sse2.mullo_epi16(Sse2.packs_epi32(intsLo, intsHi), b), 8); + } + } + default: + { + if (Constant.IsConstantExpression(a)) + { + return mullo_epi8(div_epu8(b, gcd_epu8(a, b)), a); + } + else + { + return mullo_epi8(div_epu8(a, gcd_epu8(a, b)), b); + } + } + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_lcm_epu8(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + if (Constant.IsConstantExpression(a)) + { + return mm256_mullo_epi8(mm256_div_epu8(b, mm256_gcd_epu8(a, b)), a); + } + else + { + return mm256_mullo_epi8(mm256_div_epu8(a, mm256_gcd_epu8(a, b)), b); + } + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 lcm_epu16(v128 a, v128 b, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(a)) + { + return Sse2.mullo_epi16(div_epu16(b, gcd_epu16(a, b), elements), a); + } + else + { + return Sse2.mullo_epi16(div_epu16(a, gcd_epu16(a, b), elements), b); + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_lcm_epu16(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + if (Constant.IsConstantExpression(a)) + { + return Avx2.mm256_mullo_epi16(mm256_div_epu16(b, mm256_gcd_epu16(a, b)), a); + } + else + { + return Avx2.mm256_mullo_epi16(mm256_div_epu16(a, mm256_gcd_epu16(a, b)), b); + } + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 lcm_epu32(v128 a, v128 b, byte elements = 4) + { + if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(a)) + { + return mullo_epi32(div_epu32(b, gcd_epu32(a, b, elements), elements), a, elements); + } + else + { + return mullo_epi32(div_epu32(a, gcd_epu32(a, b, elements), elements), b, elements); + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_lcm_epu32(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + if (Constant.IsConstantExpression(a)) + { + return Avx2.mm256_mullo_epi32(mm256_div_epu32(b, mm256_gcd_epu32(a, b)), a); + } + else + { + return Avx2.mm256_mullo_epi32(mm256_div_epu32(a, mm256_gcd_epu32(a, b)), b); + } + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 lcm_epu64(v128 a, v128 b) + { + if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(a)) + { + return mullo_epi64(div_epu64(b, gcd_epu64(a, b)), a); + } + else + { + return mullo_epi64(div_epu64(a, gcd_epu64(a, b)), b); + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_lcm_epu64(v256 a, v256 b, byte elements = 4) + { + if (Avx2.IsAvx2Supported) + { + if (Constant.IsConstantExpression(a)) + { + return mm256_mullo_epi64(mm256_div_epu64(b, mm256_gcd_epu64(a, b, elements), elements), a, elements); + } + else + { + return mm256_mullo_epi64(mm256_div_epu64(a, mm256_gcd_epu64(a, b, elements), elements), b, elements); + } + } + else throw new IllegalInstructionException(); + } + } + } + + unsafe public static partial class maxmath { /// Returns the least common multiple of two s. @@ -25,8 +247,8 @@ public static UInt128 lcm(UInt128 x, UInt128 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static UInt128 lcm(Int128 x, Int128 y) { - UInt128 absX = Xse.constexpr.IS_TRUE(x >= 0) ? (UInt128)x : (UInt128)abs(x); - UInt128 absY = Xse.constexpr.IS_TRUE(x >= 0) ? (UInt128)y : (UInt128)abs(y); + UInt128 absX = (UInt128)abs(x); + UInt128 absY = (UInt128)abs(y); if (Constant.IsConstantExpression(absX)) { @@ -51,13 +273,20 @@ public static uint lcm(byte x, byte y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte2 lcm(byte2 x, byte2 y) { - if (Constant.IsConstantExpression(x)) + if (Sse2.IsSse2Supported) { - return (y / gcd(x, y)) * x; + return Xse.lcm_epu8(x, y, 2); } else { - return (x / gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -65,13 +294,20 @@ public static byte2 lcm(byte2 x, byte2 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte3 lcm(byte3 x, byte3 y) { - if (Constant.IsConstantExpression(x)) + if (Sse2.IsSse2Supported) { - return (y / gcd(x, y)) * x; + return Xse.lcm_epu8(x, y, 3); } else { - return (x / gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -79,13 +315,20 @@ public static byte3 lcm(byte3 x, byte3 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte4 lcm(byte4 x, byte4 y) { - if (Constant.IsConstantExpression(x)) + if (Sse2.IsSse2Supported) { - return (y / gcd(x, y)) * x; + return Xse.lcm_epu8(x, y, 4); } else { - return (x / gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -93,13 +336,20 @@ public static byte4 lcm(byte4 x, byte4 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte8 lcm(byte8 x, byte8 y) { - if (Constant.IsConstantExpression(x)) + if (Sse2.IsSse2Supported) { - return (y / gcd(x, y)) * x; + return Xse.lcm_epu8(x, y, 8); } else { - return (x / gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -107,13 +357,20 @@ public static byte8 lcm(byte8 x, byte8 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte16 lcm(byte16 x, byte16 y) { - if (Constant.IsConstantExpression(x)) + if (Sse2.IsSse2Supported) { - return (y / gcd(x, y)) * x; + return Xse.lcm_epu8(x, y, 16); } else { - return (x / gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -121,13 +378,20 @@ public static byte16 lcm(byte16 x, byte16 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte32 lcm(byte32 x, byte32 y) { - if (Constant.IsConstantExpression(x)) + if (Avx2.IsAvx2Supported) { - return (y / gcd(x, y)) * x; + return Xse.mm256_lcm_epu8(x, y); } else { - return (x / gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -144,16 +408,23 @@ public static uint lcm(sbyte x, sbyte y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte2 lcm(sbyte2 x, sbyte2 y) { - byte2 absX = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (byte2)x : (byte2)abs(x); - byte2 absY = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (byte2)y : (byte2)abs(y); + byte2 absX = (byte2)abs(x); + byte2 absY = (byte2)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Sse2.IsSse2Supported) { - return (absY / gcd(absX, absY)) * absX; + return Xse.lcm_epu8(absX, absY, 2); } else { - return (absX / gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -161,16 +432,23 @@ public static byte2 lcm(sbyte2 x, sbyte2 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte3 lcm(sbyte3 x, sbyte3 y) { - byte3 absX = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (byte3)x : (byte3)abs(x); - byte3 absY = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (byte3)y : (byte3)abs(y); + byte3 absX = (byte3)abs(x); + byte3 absY = (byte3)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Sse2.IsSse2Supported) { - return (absY / gcd(absX, absY)) * absX; + return Xse.lcm_epu8(absX, absY, 3); } else { - return (absX / gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -178,16 +456,23 @@ public static byte3 lcm(sbyte3 x, sbyte3 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte4 lcm(sbyte4 x, sbyte4 y) { - byte4 absX = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (byte4)x : (byte4)abs(x); - byte4 absY = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (byte4)y : (byte4)abs(y); + byte4 absX = (byte4)abs(x); + byte4 absY = (byte4)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Sse2.IsSse2Supported) { - return (absY / gcd(absX, absY)) * absX; + return Xse.lcm_epu8(absX, absY, 4); } else { - return (absX / gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -195,16 +480,23 @@ public static byte4 lcm(sbyte4 x, sbyte4 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte8 lcm(sbyte8 x, sbyte8 y) { - byte8 absX = Xse.constexpr.IS_TRUE(all(x >= 0)) ? (byte8)x : (byte8)abs(x); - byte8 absY = Xse.constexpr.IS_TRUE(all(x >= 0)) ? (byte8)y : (byte8)abs(y); + byte8 absX = (byte8)abs(x); + byte8 absY = (byte8)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Sse2.IsSse2Supported) { - return (absY / gcd(absX, absY)) * absX; + return Xse.lcm_epu8(absX, absY, 8); } else { - return (absX / gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -212,16 +504,23 @@ public static byte8 lcm(sbyte8 x, sbyte8 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte16 lcm(sbyte16 x, sbyte16 y) { - byte16 absX = Xse.constexpr.IS_TRUE(all(x >= 0)) ? (byte16)x : (byte16)abs(x); - byte16 absY = Xse.constexpr.IS_TRUE(all(x >= 0)) ? (byte16)y : (byte16)abs(y); + byte16 absX = (byte16)abs(x); + byte16 absY = (byte16)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Sse2.IsSse2Supported) { - return (absY / gcd(absX, absY)) * absX; + return Xse.lcm_epu8(absX, absY, 16); } else { - return (absX / gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -229,16 +528,23 @@ public static byte16 lcm(sbyte16 x, sbyte16 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte32 lcm(sbyte32 x, sbyte32 y) { - byte32 absX = Xse.constexpr.IS_TRUE(all(x >= 0)) ? (byte32)x : (byte32)abs(x); - byte32 absY = Xse.constexpr.IS_TRUE(all(x >= 0)) ? (byte32)y : (byte32)abs(y); + byte32 absX = (byte32)abs(x); + byte32 absY = (byte32)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Avx2.IsAvx2Supported) { - return (absY / gcd(absX, absY)) * absX; + return Xse.mm256_lcm_epu8(absX, absY); } else { - return (absX / gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -254,13 +560,20 @@ public static uint lcm(ushort x, ushort y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort2 lcm(ushort2 x, ushort2 y) { - if (Constant.IsConstantExpression(x)) + if (Sse2.IsSse2Supported) { - return (y / gcd(x, y)) * x; + return Xse.lcm_epu16(x, y, 2); } else { - return (x / gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -268,13 +581,20 @@ public static ushort2 lcm(ushort2 x, ushort2 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort3 lcm(ushort3 x, ushort3 y) { - if (Constant.IsConstantExpression(x)) + if (Sse2.IsSse2Supported) { - return (y / gcd(x, y)) * x; + return Xse.lcm_epu16(x, y, 3); } else { - return (x / gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -282,13 +602,20 @@ public static ushort3 lcm(ushort3 x, ushort3 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort4 lcm(ushort4 x, ushort4 y) { - if (Constant.IsConstantExpression(x)) + if (Sse2.IsSse2Supported) { - return (y / gcd(x, y)) * x; + return Xse.lcm_epu16(x, y, 4); } else { - return (x / gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -296,13 +623,20 @@ public static ushort4 lcm(ushort4 x, ushort4 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort8 lcm(ushort8 x, ushort8 y) { - if (Constant.IsConstantExpression(x)) + if (Sse2.IsSse2Supported) { - return (y / gcd(x, y)) * x; + return Xse.lcm_epu16(x, y, 8); } else { - return (x / gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -310,13 +644,20 @@ public static ushort8 lcm(ushort8 x, ushort8 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort16 lcm(ushort16 x, ushort16 y) { - if (Constant.IsConstantExpression(x)) + if (Avx2.IsAvx2Supported) { - return (y / gcd(x, y)) * x; + return Xse.mm256_lcm_epu16(x, y); } else { - return (x / gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -332,16 +673,23 @@ public static uint lcm(short x, short y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort2 lcm(short2 x, short2 y) { - ushort2 absX = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (ushort2)x : (ushort2)abs(x); - ushort2 absY = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (ushort2)y : (ushort2)abs(y); + ushort2 absX = (ushort2)abs(x); + ushort2 absY = (ushort2)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Sse2.IsSse2Supported) { - return (absY / gcd(absX, absY)) * absX; + return Xse.lcm_epu16(absX, absY, 2); } else { - return (absX / gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -349,16 +697,23 @@ public static ushort2 lcm(short2 x, short2 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort3 lcm(short3 x, short3 y) { - ushort3 absX = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (ushort3)x : (ushort3)abs(x); - ushort3 absY = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (ushort3)y : (ushort3)abs(y); + ushort3 absX = (ushort3)abs(x); + ushort3 absY = (ushort3)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Sse2.IsSse2Supported) { - return (absY / gcd(absX, absY)) * absX; + return Xse.lcm_epu16(absX, absY, 3); } else { - return (absX / gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -366,16 +721,23 @@ public static ushort3 lcm(short3 x, short3 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort4 lcm(short4 x, short4 y) { - ushort4 absX = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (ushort4)x : (ushort4)abs(x); - ushort4 absY = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (ushort4)y : (ushort4)abs(y); + ushort4 absX = (ushort4)abs(x); + ushort4 absY = (ushort4)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Sse2.IsSse2Supported) { - return (absY / gcd(absX, absY)) * absX; + return Xse.lcm_epu16(absX, absY, 4); } else { - return (absX / gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -383,16 +745,23 @@ public static ushort4 lcm(short4 x, short4 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort8 lcm(short8 x, short8 y) { - ushort8 absX = Xse.constexpr.IS_TRUE(all(x >= 0)) ? (ushort8)x : (ushort8)abs(x); - ushort8 absY = Xse.constexpr.IS_TRUE(all(x >= 0)) ? (ushort8)y : (ushort8)abs(y); + ushort8 absX = (ushort8)abs(x); + ushort8 absY = (ushort8)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Sse2.IsSse2Supported) { - return (absY / gcd(absX, absY)) * absX; + return Xse.lcm_epu16(absX, absY, 8); } else { - return (absX / gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -400,16 +769,23 @@ public static ushort8 lcm(short8 x, short8 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort16 lcm(short16 x, short16 y) { - ushort16 absX = Xse.constexpr.IS_TRUE(all(x >= 0)) ? (ushort16)x : (ushort16)abs(x); - ushort16 absY = Xse.constexpr.IS_TRUE(all(x >= 0)) ? (ushort16)y : (ushort16)abs(y); + ushort16 absX = (ushort16)abs(x); + ushort16 absY = (ushort16)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Avx2.IsAvx2Supported) { - return (absY / gcd(absX, absY)) * absX; + return Xse.mm256_lcm_epu16(absX, absY); } else { - return (absX / gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -438,13 +814,20 @@ public static uint2 lcm(int2 x, int2 y) uint2 absX = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (uint2)x : (uint2)abs(x); uint2 absY = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (uint2)y : (uint2)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Sse2.IsSse2Supported) { - return div(absY, gcd(absX, absY)) * absX; + return RegisterConversion.ToUInt2(Xse.lcm_epu32(RegisterConversion.ToV128(absX), RegisterConversion.ToV128(absY), 2)); } else { - return div(absX, gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -455,13 +838,20 @@ public static uint3 lcm(int3 x, int3 y) uint3 absX = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (uint3)x : (uint3)abs(x); uint3 absY = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (uint3)y : (uint3)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Sse2.IsSse2Supported) { - return div(absY, gcd(absX, absY)) * absX; + return RegisterConversion.ToUInt3(Xse.lcm_epu32(RegisterConversion.ToV128(absX), RegisterConversion.ToV128(absY), 3)); } else { - return div(absX, gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -472,13 +862,20 @@ public static uint4 lcm(int4 x, int4 y) uint4 absX = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (uint4)x : (uint4)abs(x); uint4 absY = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (uint4)y : (uint4)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Sse2.IsSse2Supported) { - return div(absY, gcd(absX, absY)) * absX; + return RegisterConversion.ToUInt4(Xse.lcm_epu32(RegisterConversion.ToV128(absX), RegisterConversion.ToV128(absY), 4)); } else { - return div(absX, gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -489,13 +886,20 @@ public static uint8 lcm(int8 x, int8 y) uint8 absX = Xse.constexpr.IS_TRUE(all(x >= 0)) ? (uint8)x : (uint8)abs(x); uint8 absY = Xse.constexpr.IS_TRUE(all(x >= 0)) ? (uint8)y : (uint8)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Avx2.IsAvx2Supported) { - return (absY / gcd(absX, absY)) * absX; + return Xse.mm256_lcm_epu32(absX, absY); } else { - return (absX / gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -519,13 +923,20 @@ public static uint lcm(uint x, uint y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint2 lcm(uint2 x, uint2 y) { - if (Constant.IsConstantExpression(x)) + if (Sse2.IsSse2Supported) { - return div(y, gcd(x, y)) * x; + return RegisterConversion.ToUInt2(Xse.lcm_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 2)); } else { - return div(x, gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -533,13 +944,20 @@ public static uint2 lcm(uint2 x, uint2 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint3 lcm(uint3 x, uint3 y) { - if (Constant.IsConstantExpression(x)) + if (Sse2.IsSse2Supported) { - return div(y, gcd(x, y)) * x; + return RegisterConversion.ToUInt3(Xse.lcm_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 3)); } else { - return div(x, gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -547,13 +965,20 @@ public static uint3 lcm(uint3 x, uint3 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint4 lcm(uint4 x, uint4 y) { - if (Constant.IsConstantExpression(x)) + if (Sse2.IsSse2Supported) { - return div(y, gcd(x, y)) * x; + return RegisterConversion.ToUInt4(Xse.lcm_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 4)); } else { - return div(x, gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -561,13 +986,20 @@ public static uint4 lcm(uint4 x, uint4 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint8 lcm(uint8 x, uint8 y) { - if (Constant.IsConstantExpression(x)) + if (Avx2.IsAvx2Supported) { - return div(y, gcd(x, y)) * x; + return Xse.mm256_lcm_epu32(x, y); } else { - return div(x, gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -579,7 +1011,7 @@ public static ulong lcm(long x, long y) ulong absX = Xse.constexpr.IS_TRUE(x >= 0) ? (ulong)x : (ulong)math.abs(x); ulong absY = Xse.constexpr.IS_TRUE(x >= 0) ? (ulong)y : (ulong)math.abs(y); - if (Constant.IsConstantExpression(absX)) + if (Constant.IsConstantExpression(x)) { return (absY / gcd(absX, absY)) * absX; } @@ -593,16 +1025,23 @@ public static ulong lcm(long x, long y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong2 lcm(long2 x, long2 y) { - ulong2 absX = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (ulong2)x : (ulong2)abs(x); - ulong2 absY = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (ulong2)y : (ulong2)abs(y); + ulong2 absX = (ulong2)abs(x); + ulong2 absY = (ulong2)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Sse2.IsSse2Supported) { - return (absY / gcd(absX, absY)) * absX; + return Xse.lcm_epu64(absX, absY); } else { - return (absX / gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -610,16 +1049,23 @@ public static ulong2 lcm(long2 x, long2 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong3 lcm(long3 x, long3 y) { - ulong3 absX = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (ulong3)x : (ulong3)abs(x); - ulong3 absY = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (ulong3)y : (ulong3)abs(y); + ulong3 absX = (ulong3)abs(x); + ulong3 absY = (ulong3)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Avx2.IsAvx2Supported) { - return (absY / gcd(absX, absY)) * absX; + return Xse.mm256_lcm_epu64(absX, absY, 3); } else { - return (absX / gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -627,16 +1073,23 @@ public static ulong3 lcm(long3 x, long3 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong4 lcm(long4 x, long4 y) { - ulong4 absX = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (ulong4)x : (ulong4)abs(x); - ulong4 absY = Xse.constexpr.IS_TRUE(math.all(x >= 0)) ? (ulong4)y : (ulong4)abs(y); + ulong4 absX = (ulong4)abs(x); + ulong4 absY = (ulong4)abs(y); - if (Constant.IsConstantExpression(absX)) + if (Avx2.IsAvx2Supported) { - return (absY / gcd(absX, absY)) * absX; + return Xse.mm256_lcm_epu64(absX, absY, 4); } else { - return (absX / gcd(absX, absY)) * absY; + if (Constant.IsConstantExpression(x)) + { + return (absY / gcd(absX, absY)) * absX; + } + else + { + return (absX / gcd(absX, absY)) * absY; + } } } @@ -659,13 +1112,20 @@ public static ulong lcm(ulong x, ulong y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong2 lcm(ulong2 x, ulong2 y) { - if (Constant.IsConstantExpression(x)) + if (Sse2.IsSse2Supported) { - return (y / gcd(x, y)) * x; + return Xse.lcm_epu64(x, y); } else { - return (x / gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -673,13 +1133,20 @@ public static ulong2 lcm(ulong2 x, ulong2 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong3 lcm(ulong3 x, ulong3 y) { - if (Constant.IsConstantExpression(x)) + if (Avx2.IsAvx2Supported) { - return (y / gcd(x, y)) * x; + return Xse.mm256_lcm_epu64(x, y, 3); } else { - return (x / gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } @@ -687,13 +1154,20 @@ public static ulong3 lcm(ulong3 x, ulong3 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong4 lcm(ulong4 x, ulong4 y) { - if (Constant.IsConstantExpression(x)) + if (Avx2.IsAvx2Supported) { - return (y / gcd(x, y)) * x; + return Xse.mm256_lcm_epu64(x, y, 4); } else { - return (x / gcd(x, y)) * y; + if (Constant.IsConstantExpression(x)) + { + return (y / gcd(x, y)) * x; + } + else + { + return (x / gcd(x, y)) * y; + } } } } diff --git a/Runtime/Math Lib/Functions/Arithmetic/Integer/Square Root.cs b/Runtime/Math Lib/Functions/Arithmetic/Integer/Square Root.cs index 647e31d..cbe29c6 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Integer/Square Root.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Integer/Square Root.cs @@ -20,11 +20,11 @@ public static v128 sqrt_epi8(v128 a, byte elements = 16) { if (elements <= 4) { - v128 toFloat = Xse.cvtepu8_ps(a); + v128 toFloat = cvtepu8_ps(a); v128 sqrt = Sse.rcp_ps(Sse.rsqrt_ps(toFloat)); v128 toInt = Sse2.cvttps_epi32(sqrt); - a = Xse.cvtepi32_epi8(toInt, elements); + a = cvtepi32_epi8(toInt, elements); } else if (elements <= 8) { @@ -1341,7 +1341,7 @@ public static uint2 intsqrt(uint2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.sqrt_epu32(RegisterConversion.ToV128(x), 2)); + return RegisterConversion.ToUInt2(Xse.sqrt_epu32(RegisterConversion.ToV128(x), 2)); } else { @@ -1355,7 +1355,7 @@ public static uint3 intsqrt(uint3 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.sqrt_epu32(RegisterConversion.ToV128(x), 3)); + return RegisterConversion.ToUInt3(Xse.sqrt_epu32(RegisterConversion.ToV128(x), 3)); } else { @@ -1369,7 +1369,7 @@ public static uint4 intsqrt(uint4 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.sqrt_epu32(RegisterConversion.ToV128(x), 4)); + return RegisterConversion.ToUInt4(Xse.sqrt_epu32(RegisterConversion.ToV128(x), 4)); } else { @@ -1418,7 +1418,7 @@ public static int2 intsqrt(int2 x) if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.sqrt_epi32(RegisterConversion.ToV128(x), 2)); + return RegisterConversion.ToInt2(Xse.sqrt_epi32(RegisterConversion.ToV128(x), 2)); } else { @@ -1436,7 +1436,7 @@ public static int3 intsqrt(int3 x) if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.sqrt_epi32(RegisterConversion.ToV128(x), 3)); + return RegisterConversion.ToInt3(Xse.sqrt_epi32(RegisterConversion.ToV128(x), 3)); } else { @@ -1455,7 +1455,7 @@ public static int4 intsqrt(int4 x) if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.sqrt_epi32(RegisterConversion.ToV128(x), 4)); + return RegisterConversion.ToInt4(Xse.sqrt_epi32(RegisterConversion.ToV128(x), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Integer/k-permutations of n.cs b/Runtime/Math Lib/Functions/Arithmetic/Integer/k-permutations of n.cs new file mode 100644 index 0000000..9d8d48a --- /dev/null +++ b/Runtime/Math Lib/Functions/Arithmetic/Integer/k-permutations of n.cs @@ -0,0 +1,2268 @@ +using System.Runtime.CompilerServices; +using Unity.Burst.Intrinsics; +using Unity.Burst.CompilerServices; +using Unity.Mathematics; +using MaxMath.Intrinsics; +using DevTools; + +using static Unity.Burst.Intrinsics.X86; +using static MaxMath.LUT.FACTORIAL; + +namespace MaxMath +{ + namespace Intrinsics + { + unsafe public static partial class Xse + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v128 naiveperm_epu8(v128 n, v128 k, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + v128 nom = gamma_epu8(n, true, elements); + v128 denom = gamma_epu8(Sse2.sub_epi8(n, k), true, elements); + + return div_epu8(nom, denom, elements); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v256 mm256_naiveperm_epu8(v256 n, v256 k) + { + if (Avx2.IsAvx2Supported) + { + v256 nom = mm256_gamma_epu8(n, true); + v256 denom = mm256_gamma_epu8(Avx2.mm256_sub_epi8(n, k), true); + + return mm256_div_epu8(nom, denom); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v128 naiveperm_epu16(v128 n, v128 k, bool epu8range = false, byte elements = 8) + { + v128 nom; + v128 denom; + if (Sse2.IsSse2Supported) + { + if (epu8range || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U8, elements)) + { + if (Ssse3.IsSsse3Supported) + { + nom = gamma_epu16_epu8range(n); + denom = gamma_epu16_epu8range(Sse2.sub_epi16(n, k)); + + return div_epu16(nom, denom, elements); + } + } + + nom = gamma_epu16(n, true, elements); + denom = gamma_epu16(Sse2.sub_epi16(n, k), true, elements); + + return div_epu16(nom, denom, elements); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v256 mm256_naiveperm_epu16(v256 n, v256 k, bool epu8range = false) + { + if (Avx2.IsAvx2Supported) + { + if (epu8range || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U8)) + { + v256 nom = mm256_gamma_epu16_epu8range(n); + v256 denom = mm256_gamma_epu16_epu8range(Avx2.mm256_sub_epi16(n, k)); + + return mm256_div_epu16(nom, denom); + } + else + { + v256 nom = mm256_gamma_epu16(n, true); + v256 denom = mm256_gamma_epu16(Avx2.mm256_sub_epi16(n, k), true); + + return mm256_div_epu16(nom, denom); + } + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v128 naiveperm_epu32(v128 n, v128 k, byte elements = 4) + { + if (Sse2.IsSse2Supported) + { + v128 nom = gamma_epu32(n, true, elements); + v128 denom = gamma_epu32(Sse2.sub_epi32(n, k), true, elements); + + return div_epu32(nom, denom, elements); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v256 mm256_naiveperm_epu32(v256 n, v256 k) + { + if (Avx2.IsAvx2Supported) + { + v256 nom = mm256_gamma_epu32(n, true); + v256 denom = mm256_gamma_epu32(Avx2.mm256_sub_epi32(n, k), true); + + return mm256_div_epu32(nom, denom); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v128 naiveperm_epu64(v128 n, v128 k) + { + if (Sse2.IsSse2Supported) + { + v128 nom = gamma_epu64(n, true); + v128 denom = gamma_epu64(Sse2.sub_epi64(n, k), true); + + return div_epu64(nom, denom); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v256 mm256_naiveperm_epu64(v256 n, v256 k, byte elements = 4) + { + if (Avx2.IsAvx2Supported) + { + v256 nom = mm256_gamma_epu64(n, true, elements); + v256 denom = mm256_gamma_epu64(Avx2.mm256_sub_epi64(n, k), true, elements); + + return mm256_div_epu64(nom, denom, elements); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 perm_epu8(v128 n, v128 k, byte unsafeLevels = 0, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { +Assert.IsNotGreater(k.Byte0, n.Byte0); +Assert.IsNotGreater(k.Byte1, n.Byte1); +if (elements > 2) +{ + Assert.IsNotGreater(k.Byte2, n.Byte2); +} +if (elements > 3) +{ + Assert.IsNotGreater(k.Byte3, n.Byte3); +} +if (elements > 4) +{ + Assert.IsNotGreater(k.Byte4, n.Byte4); + Assert.IsNotGreater(k.Byte5, n.Byte5); + Assert.IsNotGreater(k.Byte6, n.Byte6); + Assert.IsNotGreater(k.Byte7, n.Byte7); +} +if (elements > 8) +{ + Assert.IsNotGreater(k.Byte8, n.Byte8); + Assert.IsNotGreater(k.Byte9, n.Byte9); + Assert.IsNotGreater(k.Byte10, n.Byte10); + Assert.IsNotGreater(k.Byte11, n.Byte11); + Assert.IsNotGreater(k.Byte12, n.Byte12); + Assert.IsNotGreater(k.Byte13, n.Byte13); + Assert.IsNotGreater(k.Byte14, n.Byte14); + Assert.IsNotGreater(k.Byte15, n.Byte15); +} + if (unsafeLevels > 0 || constexpr.ALL_LE_EPU8(n, MAX_INVERSE_FACTORIAL_U64, elements)) + { + if (unsafeLevels > 1 || constexpr.ALL_LE_EPU8(n, MAX_INVERSE_FACTORIAL_U32, elements)) + { + if (unsafeLevels > 2 || constexpr.ALL_LE_EPU8(n, MAX_INVERSE_FACTORIAL_U16, elements)) + { + if (unsafeLevels > 3 || constexpr.ALL_LE_EPU8(n, MAX_INVERSE_FACTORIAL_U8, elements)) + { + return naiveperm_epu8(n, k, elements); + } + else + { + if (elements <= 8) + { + return cvtepi16_epi8(naiveperm_epu16(cvtepu8_epi16(n), cvtepu8_epi16(k), false, elements), elements); + } + else + { + if (Avx2.IsAvx2Supported) + { + return mm256_cvtepi16_epi8(mm256_naiveperm_epu16(Avx2.mm256_cvtepu8_epi16(n), Avx2.mm256_cvtepu8_epi16(k), false)); + } + else + { + v128 nLo16 = cvt2x2epu8_epi16(n, out v128 nHi16); + v128 kLo16 = cvt2x2epu8_epi16(k, out v128 kHi16); + + v128 resultLo = naiveperm_epu16(nLo16, kLo16, false); + v128 resultHi = naiveperm_epu16(nHi16, kHi16, false); + + return cvt2x2epi16_epi8(resultLo, resultHi); + } + } + } + } + else + { + if (elements <= 4) + { + return cvtepi32_epi8(naiveperm_epu32(cvtepu8_epi32(n), cvtepu8_epi32(k), elements), elements); + } + else + { + if (Avx2.IsAvx2Supported) + { + if (elements == 8) + { + return mm256_cvtepi32_epi8(mm256_naiveperm_epu32(Avx2.mm256_cvtepu8_epi32(n), Avx2.mm256_cvtepu8_epi32(k))); + } + else + { + v256 loN32 = Avx2.mm256_cvtepu8_epi32(n); + v256 loK32 = Avx2.mm256_cvtepu8_epi32(k); + v256 hiN32 = Avx2.mm256_cvtepu8_epi32(Sse2.bsrli_si128(n, 8 * sizeof(byte))); + v256 hiK32 = Avx2.mm256_cvtepu8_epi32(Sse2.bsrli_si128(k, 8 * sizeof(byte))); + + v128 resultLo = mm256_cvtepi32_epi8(mm256_naiveperm_epu32(loN32, loK32)); + v128 resultHi = mm256_cvtepi32_epi8(mm256_naiveperm_epu32(hiN32, hiK32)); + + return Sse2.unpacklo_epi64(resultLo, resultHi); + } + } + else + { + if (elements == 8) + { + v128 loN32 = cvtepu8_epi32(n); + v128 loK32 = cvtepu8_epi32(k); + v128 hiN32 = cvtepu8_epi32(Sse2.bsrli_si128(n, 4 * sizeof(byte))); + v128 hiK32 = cvtepu8_epi32(Sse2.bsrli_si128(k, 4 * sizeof(byte))); + + v128 resultLo = cvtepi32_epi8(naiveperm_epu32(loN32, loK32)); + v128 resultHi = cvtepi32_epi8(naiveperm_epu32(hiN32, hiK32)); + + return Sse2.unpacklo_epi32(resultLo, resultHi); + } + else + { + v128 loN16 = cvt2x2epu8_epi16(n, out v128 hiN16); + v128 loK16 = cvt2x2epu8_epi16(k, out v128 hiK16); + + v128 n32_0 = cvt2x2epu16_epi32(loN16, out v128 n32_1); + v128 n32_2 = cvt2x2epu16_epi32(hiN16, out v128 n32_3); + v128 k32_0 = cvt2x2epu16_epi32(loK16, out v128 k32_1); + v128 k32_2 = cvt2x2epu16_epi32(hiK16, out v128 k32_3); + + v128 result32_0 = naiveperm_epu32(n32_0, k32_0); + v128 result32_1 = naiveperm_epu32(n32_1, k32_1); + v128 result32_2 = naiveperm_epu32(n32_2, k32_2); + v128 result32_3 = naiveperm_epu32(n32_3, k32_3); + + v128 result16_0 = cvt2x2epi32_epi16(result32_0, result32_1); + v128 result16_1 = cvt2x2epi32_epi16(result32_2, result32_3); + + return cvt2x2epi16_epi8(result16_0, result16_1); + } + } + } + } + } + else + { + switch (elements) + { + case 2: + { + return Sse2.unpacklo_epi8(Sse2.cvtsi64x_si128((long)maxmath.perm((ulong)extract_epi8(n, 0), (ulong)extract_epi8(k, 0), maxmath.Promise.Unsafe1)), + Sse2.cvtsi64x_si128((long)maxmath.perm((ulong)extract_epi8(n, 1), (ulong)extract_epi8(k, 1), maxmath.Promise.Unsafe1))); + } + + case 3: + case 4: + { + if (Avx2.IsAvx2Supported) + { + return mm256_cvtepi64_epi8(mm256_div_epu64(mm256_gamma_epu64(Avx2.mm256_cvtepu8_epi64(n), true, elements), mm256_gamma_epu64(Avx2.mm256_sub_epi64(Avx2.mm256_cvtepu8_epi64(n), Avx2.mm256_cvtepu8_epi64(k)), true, elements), elements)); + } + else + { + return new v128((byte)maxmath.perm((ulong)extract_epi8(n, 0), (ulong)extract_epi8(k, 0), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 1), (ulong)extract_epi8(k, 1), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 2), (ulong)extract_epi8(k, 2), maxmath.Promise.Unsafe1), + (byte)(elements == 4 ? maxmath.perm((ulong)extract_epi8(n, 3), (ulong)extract_epi8(k, 3), maxmath.Promise.Unsafe1) : 0), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0); + } + } + + case 8: + { + if (Avx2.IsAvx2Supported) + { + v256 nLo = Avx2.mm256_cvtepu8_epi64(n); + v256 kLo = Avx2.mm256_cvtepu8_epi64(k); + v256 nHi = Avx2.mm256_cvtepu8_epi64(Sse2.bsrli_si128(n, 4 * sizeof(byte))); + v256 kHi = Avx2.mm256_cvtepu8_epi64(Sse2.bsrli_si128(k, 4 * sizeof(byte))); + + v128 lo = mm256_cvtepi64_epi8(mm256_naiveperm_epu64(nLo, kLo)); + v128 hi = mm256_cvtepi64_epi8(mm256_naiveperm_epu64(nHi, kHi)); + + return Sse2.unpacklo_epi32(lo, hi); + } + else + { + return new v128((byte)maxmath.perm((ulong)extract_epi8(n, 0), (ulong)extract_epi8(k, 0), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 1), (ulong)extract_epi8(k, 1), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 2), (ulong)extract_epi8(k, 2), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 3), (ulong)extract_epi8(k, 3), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 4), (ulong)extract_epi8(k, 4), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 5), (ulong)extract_epi8(k, 5), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 6), (ulong)extract_epi8(k, 6), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 7), (ulong)extract_epi8(k, 7), maxmath.Promise.Unsafe1), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0); + } + } + + default: + { + if (Avx2.IsAvx2Supported) + { + v256 n0 = Avx2.mm256_cvtepu8_epi64(n); + v256 k0 = Avx2.mm256_cvtepu8_epi64(k); + v256 n1 = Avx2.mm256_cvtepu8_epi64(Sse2.bsrli_si128(n, 4 * sizeof(byte))); + v256 k1 = Avx2.mm256_cvtepu8_epi64(Sse2.bsrli_si128(k, 4 * sizeof(byte))); + v256 n2 = Avx2.mm256_cvtepu8_epi64(Sse2.bsrli_si128(n, 8 * sizeof(byte))); + v256 k2 = Avx2.mm256_cvtepu8_epi64(Sse2.bsrli_si128(k, 8 * sizeof(byte))); + v256 n3 = Avx2.mm256_cvtepu8_epi64(Sse2.bsrli_si128(n, 12 * sizeof(byte))); + v256 k3 = Avx2.mm256_cvtepu8_epi64(Sse2.bsrli_si128(k, 12 * sizeof(byte))); + + v128 result0 = mm256_cvtepi64_epi8(mm256_naiveperm_epu64(n0, k0)); + v128 result1 = mm256_cvtepi64_epi8(mm256_naiveperm_epu64(n1, k1)); + v128 result2 = mm256_cvtepi64_epi8(mm256_naiveperm_epu64(n2, k2)); + v128 result3 = mm256_cvtepi64_epi8(mm256_naiveperm_epu64(n3, k3)); + + return Sse2.unpacklo_epi64(Sse2.unpacklo_epi32(result0, result1), Sse2.unpacklo_epi32(result2, result3)); + } + else + { + return new v128((byte)maxmath.perm((ulong)extract_epi8(n, 0), (ulong)extract_epi8(k, 0), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 1), (ulong)extract_epi8(k, 1), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 2), (ulong)extract_epi8(k, 2), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 3), (ulong)extract_epi8(k, 3), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 4), (ulong)extract_epi8(k, 4), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 5), (ulong)extract_epi8(k, 5), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 6), (ulong)extract_epi8(k, 6), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 7), (ulong)extract_epi8(k, 7), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 8), (ulong)extract_epi8(k, 8), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 9), (ulong)extract_epi8(k, 9), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 10), (ulong)extract_epi8(k, 10), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 11), (ulong)extract_epi8(k, 11), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 12), (ulong)extract_epi8(k, 12), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 13), (ulong)extract_epi8(k, 13), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 14), (ulong)extract_epi8(k, 14), maxmath.Promise.Unsafe1), + (byte)maxmath.perm((ulong)extract_epi8(n, 15), (ulong)extract_epi8(k, 15), maxmath.Promise.Unsafe1)); + } + } + } + } + } + + + if (elements <= 8) + { + return cvtepi16_epi8(perm_epu16(cvtepu8_epi16(n), cvtepu8_epi16(k), elements: elements), elements); + } + else + { + if (Avx2.IsAvx2Supported) + { + return mm256_cvtepi16_epi8(mm256_perm_epu16(Avx2.mm256_cvtepu8_epi16(n), Avx2.mm256_cvtepu8_epi16(k))); + } + else + { + v128 ZERO = Sse2.setzero_si128(); + + v128 resultsFoundMask = Sse2.cmpeq_epi8(k, ZERO); + v128 results = Sse2.sub_epi8(ZERO, resultsFoundMask); + + k = dec_epi8(k); + v128 p = n; + n = dec_epi8(n); + + v128 cmp = Sse2.cmpeq_epi8(ZERO, k); + results = blendv_si128(results, p, cmp); + resultsFoundMask = Sse2.or_si128(resultsFoundMask, cmp); + + while (Hint.Likely(notalltrue_epi128(resultsFoundMask, elements))) + { + k = dec_epi8(k); + p = mullo_epi8(p, n, elements); + n = dec_epi8(n); + + cmp = Sse2.cmpeq_epi8(ZERO, k); + results = blendv_si128(results, p, cmp); + resultsFoundMask = Sse2.or_si128(resultsFoundMask, cmp); + } + + return results; + } + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_perm_epu8(v256 n, v256 k, byte unsafeLevels = 0) + { + if (Avx2.IsAvx2Supported) + { +Assert.IsNotGreater(k.Byte0, n.Byte0); +Assert.IsNotGreater(k.Byte1, n.Byte1); +Assert.IsNotGreater(k.Byte2, n.Byte2); +Assert.IsNotGreater(k.Byte3, n.Byte3); +Assert.IsNotGreater(k.Byte4, n.Byte4); +Assert.IsNotGreater(k.Byte5, n.Byte5); +Assert.IsNotGreater(k.Byte6, n.Byte6); +Assert.IsNotGreater(k.Byte7, n.Byte7); +Assert.IsNotGreater(k.Byte8, n.Byte8); +Assert.IsNotGreater(k.Byte9, n.Byte9); +Assert.IsNotGreater(k.Byte10, n.Byte10); +Assert.IsNotGreater(k.Byte11, n.Byte11); +Assert.IsNotGreater(k.Byte12, n.Byte12); +Assert.IsNotGreater(k.Byte13, n.Byte13); +Assert.IsNotGreater(k.Byte14, n.Byte14); +Assert.IsNotGreater(k.Byte15, n.Byte15); +Assert.IsNotGreater(k.Byte16, n.Byte16); +Assert.IsNotGreater(k.Byte17, n.Byte17); +Assert.IsNotGreater(k.Byte18, n.Byte18); +Assert.IsNotGreater(k.Byte19, n.Byte19); +Assert.IsNotGreater(k.Byte20, n.Byte20); +Assert.IsNotGreater(k.Byte21, n.Byte21); +Assert.IsNotGreater(k.Byte22, n.Byte22); +Assert.IsNotGreater(k.Byte23, n.Byte23); +Assert.IsNotGreater(k.Byte24, n.Byte24); +Assert.IsNotGreater(k.Byte25, n.Byte25); +Assert.IsNotGreater(k.Byte26, n.Byte26); +Assert.IsNotGreater(k.Byte27, n.Byte27); +Assert.IsNotGreater(k.Byte28, n.Byte28); +Assert.IsNotGreater(k.Byte29, n.Byte29); +Assert.IsNotGreater(k.Byte30, n.Byte30); +Assert.IsNotGreater(k.Byte31, n.Byte31); + + if (unsafeLevels > 0 || constexpr.ALL_LE_EPU8(n, MAX_INVERSE_FACTORIAL_U64)) + { + if (unsafeLevels > 1 || constexpr.ALL_LE_EPU8(n, MAX_INVERSE_FACTORIAL_U32)) + { + if (unsafeLevels > 2 || constexpr.ALL_LE_EPU8(n, MAX_INVERSE_FACTORIAL_U16)) + { + if (unsafeLevels > 3 || constexpr.ALL_LE_EPU8(n, MAX_INVERSE_FACTORIAL_U8)) + { + return mm256_naiveperm_epu8(n, k); + } + else + { + v256 nLo16 = mm256_cvt2x2epu8_epi16(n, out v256 nHi16); + v256 kLo16 = mm256_cvt2x2epu8_epi16(k, out v256 kHi16); + + return mm256_cvt2x2epi16_epi8(mm256_naiveperm_epu16(nLo16, kLo16), mm256_naiveperm_epu16(nHi16, kHi16)); + } + } + else + { + v256 loN16 = mm256_cvt2x2epu8_epi16(n, out v256 hiN16); + v256 loK16 = mm256_cvt2x2epu8_epi16(k, out v256 hiK16); + + v256 n32_0 = mm256_cvt2x2epu16_epi32(loN16, out v256 n32_1); + v256 n32_2 = mm256_cvt2x2epu16_epi32(hiN16, out v256 n32_3); + v256 k32_0 = mm256_cvt2x2epu16_epi32(loK16, out v256 k32_1); + v256 k32_2 = mm256_cvt2x2epu16_epi32(hiK16, out v256 k32_3); + + v256 result32_0 = mm256_naiveperm_epu32(n32_0, k32_0); + v256 result32_1 = mm256_naiveperm_epu32(n32_1, k32_1); + v256 result32_2 = mm256_naiveperm_epu32(n32_2, k32_2); + v256 result32_3 = mm256_naiveperm_epu32(n32_3, k32_3); + + v256 result16_0 = mm256_cvt2x2epi32_epi16(result32_0, result32_1); + v256 result16_1 = mm256_cvt2x2epi32_epi16(result32_2, result32_3); + + return mm256_cvt2x2epi16_epi8(result16_0, result16_1); + } + } + else + { + v256 loN16 = mm256_cvt2x2epu8_epi16(n, out v256 hiN16); + v256 loK16 = mm256_cvt2x2epu8_epi16(k, out v256 hiK16); + + v256 n32_0 = mm256_cvt2x2epu16_epi32(loN16, out v256 n32_1); + v256 n32_2 = mm256_cvt2x2epu16_epi32(hiN16, out v256 n32_3); + v256 k32_0 = mm256_cvt2x2epu16_epi32(loK16, out v256 k32_1); + v256 k32_2 = mm256_cvt2x2epu16_epi32(hiK16, out v256 k32_3); + + v256 n64_0 = mm256_cvt2x2epu32_epi64(n32_0, out v256 n64_1); + v256 n64_2 = mm256_cvt2x2epu32_epi64(n32_1, out v256 n64_3); + v256 n64_4 = mm256_cvt2x2epu32_epi64(n32_2, out v256 n64_5); + v256 n64_6 = mm256_cvt2x2epu32_epi64(n32_3, out v256 n64_7); + v256 k64_0 = mm256_cvt2x2epu32_epi64(k32_0, out v256 k64_1); + v256 k64_2 = mm256_cvt2x2epu32_epi64(k32_1, out v256 k64_3); + v256 k64_4 = mm256_cvt2x2epu32_epi64(k32_2, out v256 k64_5); + v256 k64_6 = mm256_cvt2x2epu32_epi64(k32_3, out v256 k64_7); + + v256 result64_0 = mm256_naiveperm_epu64(n64_0, k64_0); + v256 result64_1 = mm256_naiveperm_epu64(n64_1, k64_1); + v256 result64_2 = mm256_naiveperm_epu64(n64_2, k64_2); + v256 result64_3 = mm256_naiveperm_epu64(n64_3, k64_3); + v256 result64_4 = mm256_naiveperm_epu64(n64_4, k64_4); + v256 result64_5 = mm256_naiveperm_epu64(n64_5, k64_5); + v256 result64_6 = mm256_naiveperm_epu64(n64_6, k64_6); + v256 result64_7 = mm256_naiveperm_epu64(n64_7, k64_7); + + v256 result32_0 = mm256_cvt2x2epi64_epi32(result64_0, result64_1); + v256 result32_1 = mm256_cvt2x2epi64_epi32(result64_2, result64_3); + v256 result32_2 = mm256_cvt2x2epi64_epi32(result64_4, result64_5); + v256 result32_3 = mm256_cvt2x2epi64_epi32(result64_6, result64_7); + + v256 result16_0 = mm256_cvt2x2epi32_epi16(result32_0, result32_1); + v256 result16_1 = mm256_cvt2x2epi32_epi16(result32_2, result32_3); + + return mm256_cvt2x2epi16_epi8(result16_0, result16_1); + } + } + + + v256 ZERO = Avx.mm256_setzero_si256(); + + v256 resultsFoundMask = Avx2.mm256_cmpeq_epi8(k, ZERO); + v256 results = Avx2.mm256_sub_epi8(ZERO, resultsFoundMask); + + k = mm256_dec_epi8(k); + v256 p = n; + n = mm256_dec_epi8(n); + + v256 cmp = Avx2.mm256_cmpeq_epi8(ZERO, k); + results = mm256_blendv_si256(results, p, cmp); + resultsFoundMask = Avx2.mm256_or_si256(resultsFoundMask, cmp); + + while (Hint.Likely(mm256_notalltrue_epi256(resultsFoundMask, 32))) + { + k = mm256_dec_epi8(k); + p = mm256_mullo_epi8(p, n); + n = mm256_dec_epi8(n); + + cmp = Avx2.mm256_cmpeq_epi8(ZERO, k); + results = mm256_blendv_si256(results, p, cmp); + resultsFoundMask = Avx2.mm256_or_si256(resultsFoundMask, cmp); + } + + return results; + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 perm_epu16(v128 n, v128 k, byte unsafeLevels = 0, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { +Assert.IsNotGreater(k.UShort0, n.UShort0); +Assert.IsNotGreater(k.UShort1, n.UShort1); +if (elements > 2) +{ + Assert.IsNotGreater(k.UShort2, n.UShort2); +} +if (elements > 3) +{ + Assert.IsNotGreater(k.UShort3, n.UShort3); +} +if (elements > 4) +{ + Assert.IsNotGreater(k.UShort4, n.UShort4); + Assert.IsNotGreater(k.UShort5, n.UShort5); + Assert.IsNotGreater(k.UShort6, n.UShort6); + Assert.IsNotGreater(k.UShort7, n.UShort7); +} + if (unsafeLevels > 0 || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U64, elements)) + { + if (unsafeLevels > 1 || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U32, elements)) + { + if (unsafeLevels > 2 || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U16, elements)) + { + return naiveperm_epu16(n, k, unsafeLevels > 3 || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U8, elements), elements); + } + else + { + if (elements <= 4) + { + return cvtepi32_epi16(naiveperm_epu32(cvtepu16_epi32(n), cvtepu16_epi32(k), elements), elements); + } + else + { + if (Avx2.IsAvx2Supported) + { + return mm256_cvtepi32_epi16(mm256_naiveperm_epu32(Avx2.mm256_cvtepu16_epi32(n), Avx2.mm256_cvtepu16_epi32(k))); + } + else + { + v128 nLo32 = cvt2x2epu16_epi32(n, out v128 nHi32); + v128 kLo32 = cvt2x2epu16_epi32(k, out v128 kHi32); + + return cvt2x2epi32_epi16(naiveperm_epu32(nLo32, kLo32, elements), naiveperm_epu32(nHi32, kHi32, elements)); + } + } + } + } + else + { + switch (elements) + { + case 2: + { + return Sse2.unpacklo_epi16(Sse2.cvtsi32_si128((ushort)maxmath.perm((ulong)extract_epi16(n, 0), (ulong)extract_epi16(k, 0), maxmath.Promise.Unsafe1)), + Sse2.cvtsi32_si128((ushort)maxmath.perm((ulong)extract_epi16(n, 1), (ulong)extract_epi16(k, 1), maxmath.Promise.Unsafe1))); + } + + case 3: + case 4: + { + if (Avx2.IsAvx2Supported) + { + return mm256_cvtepi64_epi16(mm256_naiveperm_epu64(Avx2.mm256_cvtepu16_epi64(n), Avx2.mm256_cvtepu16_epi64(k), elements)); + } + else + { + return new v128((ushort)maxmath.perm((ulong)extract_epi16(n, 0), (ulong)extract_epi16(k, 0), maxmath.Promise.Unsafe1), + (ushort)maxmath.perm((ulong)extract_epi16(n, 1), (ulong)extract_epi16(k, 1), maxmath.Promise.Unsafe1), + (ushort)maxmath.perm((ulong)extract_epi16(n, 2), (ulong)extract_epi16(k, 2), maxmath.Promise.Unsafe1), + (ushort)(elements == 4 ? maxmath.perm((ulong)extract_epi16(n, 3), (ulong)extract_epi16(k, 3), maxmath.Promise.Unsafe1) : 0), + 0, + 0, + 0, + 0); + } + } + + default: + { + if (Avx2.IsAvx2Supported) + { + v256 n64Lo = Avx2.mm256_cvtepu16_epi64(n); + v256 k64Lo = Avx2.mm256_cvtepu16_epi64(k); + v256 n64Hi = Avx2.mm256_cvtepu16_epi64(Sse2.bsrli_si128(n, 4 * sizeof(ushort))); + v256 k64Hi = Avx2.mm256_cvtepu16_epi64(Sse2.bsrli_si128(k, 4 * sizeof(ushort))); + + v256 result64Lo = mm256_naiveperm_epu64(n64Lo, k64Lo); + v256 result64Hi = mm256_naiveperm_epu64(n64Hi, k64Hi); + + return Sse2.unpacklo_epi64(mm256_cvtepi64_epi16(result64Lo), mm256_cvtepi64_epi16(result64Hi)); + } + else + { + return new v128((ushort)maxmath.perm((ulong)extract_epi16(n, 0), (ulong)extract_epi16(k, 0), maxmath.Promise.Unsafe1), + (ushort)maxmath.perm((ulong)extract_epi16(n, 1), (ulong)extract_epi16(k, 1), maxmath.Promise.Unsafe1), + (ushort)maxmath.perm((ulong)extract_epi16(n, 2), (ulong)extract_epi16(k, 2), maxmath.Promise.Unsafe1), + (ushort)maxmath.perm((ulong)extract_epi16(n, 3), (ulong)extract_epi16(k, 3), maxmath.Promise.Unsafe1), + (ushort)maxmath.perm((ulong)extract_epi16(n, 4), (ulong)extract_epi16(k, 4), maxmath.Promise.Unsafe1), + (ushort)maxmath.perm((ulong)extract_epi16(n, 5), (ulong)extract_epi16(k, 5), maxmath.Promise.Unsafe1), + (ushort)maxmath.perm((ulong)extract_epi16(n, 6), (ulong)extract_epi16(k, 6), maxmath.Promise.Unsafe1), + (ushort)maxmath.perm((ulong)extract_epi16(n, 7), (ulong)extract_epi16(k, 7), maxmath.Promise.Unsafe1)); + } + } + } + } + } + + + v128 ZERO = Sse2.setzero_si128(); + + v128 resultsFoundMask = Sse2.cmpeq_epi16(k, ZERO); + v128 results = Sse2.sub_epi16(ZERO, resultsFoundMask); + + k = dec_epi16(k); + v128 p = n; + n = dec_epi16(n); + + v128 cmp = Sse2.cmpeq_epi16(ZERO, k); + results = blendv_si128(results, p, cmp); + resultsFoundMask = Sse2.or_si128(resultsFoundMask, cmp); + + while (Hint.Likely(notalltrue_epi128(resultsFoundMask, elements))) + { + k = dec_epi16(k); + p = Sse2.mullo_epi16(p, n); + n = dec_epi16(n); + + cmp = Sse2.cmpeq_epi16(ZERO, k); + results = blendv_si128(results, p, cmp); + resultsFoundMask = Sse2.or_si128(resultsFoundMask, cmp); + } + + return results; + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_perm_epu16(v256 n, v256 k, byte unsafeLevels = 0) + { + if (Avx2.IsAvx2Supported) + { +Assert.IsNotGreater(k.UShort0, n.UShort0); +Assert.IsNotGreater(k.UShort1, n.UShort1); +Assert.IsNotGreater(k.UShort2, n.UShort2); +Assert.IsNotGreater(k.UShort3, n.UShort3); +Assert.IsNotGreater(k.UShort4, n.UShort4); +Assert.IsNotGreater(k.UShort5, n.UShort5); +Assert.IsNotGreater(k.UShort6, n.UShort6); +Assert.IsNotGreater(k.UShort7, n.UShort7); +Assert.IsNotGreater(k.UShort8, n.UShort8); +Assert.IsNotGreater(k.UShort9, n.UShort9); +Assert.IsNotGreater(k.UShort10, n.UShort10); +Assert.IsNotGreater(k.UShort11, n.UShort11); +Assert.IsNotGreater(k.UShort12, n.UShort12); +Assert.IsNotGreater(k.UShort13, n.UShort13); +Assert.IsNotGreater(k.UShort14, n.UShort14); +Assert.IsNotGreater(k.UShort15, n.UShort15); + + if (unsafeLevels > 0 || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U64)) + { + if (unsafeLevels > 1 || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U32)) + { + if (unsafeLevels > 2 || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U16)) + { + return mm256_naiveperm_epu16(n, k, unsafeLevels > 3 || constexpr.ALL_LE_EPU16(n, MAX_INVERSE_FACTORIAL_U8)); + } + else + { + v256 nLo32 = mm256_cvt2x2epu16_epi32(n, out v256 nHi32); + v256 kLo32 = mm256_cvt2x2epu16_epi32(k, out v256 kHi32); + + v256 resultLo = mm256_naiveperm_epu32(nLo32, kLo32); + v256 resultHi = mm256_naiveperm_epu32(nHi32, kHi32); + + return mm256_cvt2x2epi32_epi16(resultLo, resultHi); + } + } + else + { + v256 nLo32 = mm256_cvt2x2epu16_epi32(n, out v256 nHi32); + v256 kLo32 = mm256_cvt2x2epu16_epi32(k, out v256 kHi32); + v256 n64LoLo = mm256_cvt2x2epu32_epi64(nLo32, out v256 n64LoHi); + v256 n64HiLo = mm256_cvt2x2epu32_epi64(nHi32, out v256 n64HiHi); + v256 k64LoLo = mm256_cvt2x2epu32_epi64(kLo32, out v256 k64LoHi); + v256 k64HiLo = mm256_cvt2x2epu32_epi64(kHi32, out v256 k64HiHi); + + v256 resultLoLo = mm256_naiveperm_epu64(n64LoLo, k64LoLo); + v256 resultLoHi = mm256_naiveperm_epu64(n64LoHi, k64LoHi); + v256 resultHiLo = mm256_naiveperm_epu64(n64HiLo, k64HiLo); + v256 resultHiHi = mm256_naiveperm_epu64(n64HiHi, k64HiHi); + + v256 result32Lo = mm256_cvt2x2epi64_epi32(resultLoLo, resultLoHi); + v256 result32Hi = mm256_cvt2x2epi64_epi32(resultHiLo, resultHiHi); + + return mm256_cvt2x2epi32_epi16(result32Lo, result32Hi); + } + } + + + v256 ZERO = Avx.mm256_setzero_si256(); + + v256 resultsFoundMask = Avx2.mm256_cmpeq_epi16(k, ZERO); + v256 results = Avx2.mm256_sub_epi16(ZERO, resultsFoundMask); + + k = mm256_dec_epi16(k); + v256 p = n; + n = mm256_dec_epi16(n); + + v256 cmp = Avx2.mm256_cmpeq_epi16(ZERO, k); + results = mm256_blendv_si256(results, p, cmp); + resultsFoundMask = Avx2.mm256_or_si256(resultsFoundMask, cmp); + + while (Hint.Likely(mm256_notalltrue_epi256(resultsFoundMask, 16))) + { + k = mm256_dec_epi16(k); + p = Avx2.mm256_mullo_epi16(p, n); + n = mm256_dec_epi16(n); + + cmp = Avx2.mm256_cmpeq_epi16(ZERO, k); + results = mm256_blendv_si256(results, p, cmp); + resultsFoundMask = Avx2.mm256_or_si256(resultsFoundMask, cmp); + } + + return results; + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 perm_epu32(v128 n, v128 k, byte unsafeLevels = 0, byte elements = 4) + { + if (Sse2.IsSse2Supported) + { +Assert.IsNotGreater(k.UInt0, n.UInt0); +Assert.IsNotGreater(k.UInt1, n.UInt1); +if (elements > 2) +{ + Assert.IsNotGreater(k.UInt2, n.UInt2); +} +if (elements > 3) +{ + Assert.IsNotGreater(k.UInt3, n.UInt3); +} + if (unsafeLevels > 0 || constexpr.ALL_LE_EPU32(n, MAX_INVERSE_FACTORIAL_U64, elements)) + { + if (unsafeLevels > 1 || constexpr.ALL_LE_EPU32(n, MAX_INVERSE_FACTORIAL_U32, elements)) + { + return naiveperm_epu32(n, k, elements); + } + else + { + if (elements > 2) + { + if (Avx2.IsAvx2Supported) + { + return mm256_cvtepi64_epi32(mm256_naiveperm_epu64(Avx2.mm256_cvtepu32_epi64(n), Avx2.mm256_cvtepu32_epi64(k), elements)); + } + else + { + v128 lo = Sse2.unpacklo_epi32(Sse2.cvtsi32_si128((int)maxmath.perm((ulong)extract_epi32(n, 0), (ulong)extract_epi32(k, 0), maxmath.Promise.Unsafe1)), + Sse2.cvtsi32_si128((int)maxmath.perm((ulong)extract_epi32(n, 1), (ulong)extract_epi32(k, 1), maxmath.Promise.Unsafe1))); + v128 hi = Sse2.cvtsi32_si128((int)maxmath.perm((ulong)extract_epi32(n, 2), (ulong)extract_epi32(k, 2), maxmath.Promise.Unsafe1)); + + if (elements == 4) + { + hi = Sse2.unpacklo_epi32(hi, Sse2.cvtsi32_si128((int)maxmath.perm((ulong)extract_epi32(n, 3), (ulong)extract_epi32(k, 3), maxmath.Promise.Unsafe1))); + } + + return Sse2.unpacklo_epi64(lo, hi); + } + } + else + { + return Sse2.unpacklo_epi32(Sse2.cvtsi32_si128((int)maxmath.perm((ulong)extract_epi32(n, 0), (ulong)extract_epi32(k, 0), maxmath.Promise.Unsafe1)), + Sse2.cvtsi32_si128((int)maxmath.perm((ulong)extract_epi32(n, 1), (ulong)extract_epi32(k, 1), maxmath.Promise.Unsafe1))); + } + } + } + + + v128 ZERO = Sse2.setzero_si128(); + + v128 resultsFoundMask = Sse2.cmpeq_epi32(k, ZERO); + v128 results = Sse2.sub_epi32(ZERO, resultsFoundMask); + + k = dec_epi32(k); + v128 p = n; + n = dec_epi32(n); + + v128 cmp = Sse2.cmpeq_epi32(ZERO, k); + results = blendv_si128(results, p, cmp); + resultsFoundMask = Sse2.or_si128(resultsFoundMask, cmp); + + while (Hint.Likely(notalltrue_epi128(resultsFoundMask, elements))) + { + k = dec_epi32(k); + p = mullo_epi32(p, n, elements); + n = dec_epi32(n); + + cmp = Sse2.cmpeq_epi32(ZERO, k); + results = blendv_si128(results, p, cmp); + resultsFoundMask = Sse2.or_si128(resultsFoundMask, cmp); + } + + return results; + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_perm_epu32(v256 n, v256 k, byte unsafeLevels = 0) + { + if (Avx2.IsAvx2Supported) + { +Assert.IsNotGreater(k.UInt0, n.UInt0); +Assert.IsNotGreater(k.UInt1, n.UInt1); +Assert.IsNotGreater(k.UInt2, n.UInt2); +Assert.IsNotGreater(k.UInt3, n.UInt3); +Assert.IsNotGreater(k.UInt4, n.UInt4); +Assert.IsNotGreater(k.UInt5, n.UInt5); +Assert.IsNotGreater(k.UInt6, n.UInt6); +Assert.IsNotGreater(k.UInt7, n.UInt7); + + if (unsafeLevels > 0 || constexpr.ALL_LE_EPU32(n, MAX_INVERSE_FACTORIAL_U64)) + { + if (unsafeLevels > 1 || constexpr.ALL_LE_EPU32(n, MAX_INVERSE_FACTORIAL_U32)) + { + return mm256_naiveperm_epu32(n, k); + } + else + { + v256 n64Lo = mm256_cvt2x2epu32_epi64(n, out v256 n64Hi); + v256 k64Lo = mm256_cvt2x2epu32_epi64(k, out v256 k64Hi); + + v256 resultLo = mm256_naiveperm_epu64(n64Lo, k64Lo); + v256 resultHi = mm256_naiveperm_epu64(n64Hi, k64Hi); + + return mm256_cvt2x2epi64_epi32(resultLo, resultHi); + } + } + + + v256 ZERO = Avx.mm256_setzero_si256(); + + v256 resultsFoundMask = Avx2.mm256_cmpeq_epi32(k, ZERO); + v256 results = Avx2.mm256_sub_epi32(ZERO, resultsFoundMask); + + k = mm256_dec_epi32(k); + v256 p = n; + n = mm256_dec_epi32(n); + + v256 cmp = Avx2.mm256_cmpeq_epi32(ZERO, k); + results = mm256_blendv_si256(results, p, cmp); + resultsFoundMask = Avx2.mm256_or_si256(resultsFoundMask, cmp); + + while (Hint.Likely(mm256_notalltrue_epi256(resultsFoundMask, 8))) + { + k = mm256_dec_epi32(k); + p = Avx2.mm256_mullo_epi32(p, n); + n = mm256_dec_epi32(n); + + cmp = Avx2.mm256_cmpeq_epi32(ZERO, k); + results = mm256_blendv_si256(results, p, cmp); + resultsFoundMask = Avx2.mm256_or_si256(resultsFoundMask, cmp); + } + + return results; + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 perm_epu64(v128 n, v128 k, byte unsafeLevels = 0) + { + if (Sse2.IsSse2Supported) + { +Assert.IsNotGreater(k.ULong0, n.ULong0); +Assert.IsNotGreater(k.ULong1, n.ULong1); + + if (unsafeLevels > 0 || constexpr.ALL_LE_EPU64(n, MAX_INVERSE_FACTORIAL_U64)) + { + if (unsafeLevels > 1 || constexpr.ALL_LE_EPU64(n, MAX_INVERSE_FACTORIAL_U32)) + { + v128 nFactorial = gamma_epu64(n, true); + v128 nkFactorial = gamma_epu64(Sse2.sub_epi64(n, k), true); + + return usfcvttpd_epu64(Sse2.div_pd(usfcvtepu64_pd(nFactorial), usfcvtepu64_pd(nkFactorial))); + } + else + { + return Sse2.unpacklo_epi64(Sse2.cvtsi64x_si128((long)maxmath.perm(extract_epi64(n, 0), extract_epi64(k, 0), maxmath.Promise.Unsafe1)), + Sse2.cvtsi64x_si128((long)maxmath.perm(extract_epi64(n, 1), extract_epi64(k, 1), maxmath.Promise.Unsafe1))); + } + } + + + v128 ZERO = Sse2.setzero_si128(); + + v128 resultsFoundMask = cmpeq_epi64(k, ZERO); + v128 results = Sse2.sub_epi64(ZERO, resultsFoundMask); + + k = dec_epi64(k); + v128 p = n; + n = dec_epi64(n); + + v128 cmp = cmpeq_epi64(ZERO, k); + results = blendv_si128(results, p, cmp); + resultsFoundMask = Sse2.or_si128(resultsFoundMask, cmp); + + while (Hint.Likely(notalltrue_epi128(resultsFoundMask, 2))) + { + k = dec_epi64(k); + p = mullo_epi64(p, n); + n = dec_epi64(n); + + cmp = cmpeq_epi64(ZERO, k); + results = blendv_si128(results, p, cmp); + resultsFoundMask = Sse2.or_si128(resultsFoundMask, cmp); + } + + return results; + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_perm_epu64(v256 n, v256 k, byte unsafeLevels = 0, byte elements = 4) + { + if (Avx2.IsAvx2Supported) + { +Assert.IsNotGreater(k.ULong0, n.ULong0); +Assert.IsNotGreater(k.ULong1, n.ULong1); +Assert.IsNotGreater(k.ULong2, n.ULong2); +if (elements > 3) +{ + Assert.IsNotGreater(k.ULong3, n.ULong3); +} + if (unsafeLevels > 0 || constexpr.ALL_LE_EPU64(n, MAX_INVERSE_FACTORIAL_U64, elements)) + { + if (unsafeLevels > 1 || constexpr.ALL_LE_EPU64(n, MAX_INVERSE_FACTORIAL_U32, elements)) + { + v256 nFactorial = mm256_gamma_epu64(n, true); + v256 nkFactorial = mm256_gamma_epu64(Avx2.mm256_sub_epi64(n, k), true); + + return mm256_usfcvttpd_epu64(Avx.mm256_div_pd(mm256_usfcvtepu64_pd(nFactorial), mm256_usfcvtepu64_pd(nkFactorial))); + } + else + { + return mm256_naiveperm_epu64(n, k, elements); + } + } + + + v256 ZERO = Avx.mm256_setzero_si256(); + + v256 resultsFoundMask = Avx2.mm256_cmpeq_epi64(k, ZERO); + v256 results = Avx2.mm256_sub_epi64(ZERO, resultsFoundMask); + + k = mm256_dec_epi64(k); + v256 p = n; + n = mm256_dec_epi64(n); + + v256 cmp = Avx2.mm256_cmpeq_epi64(ZERO, k); + results = mm256_blendv_si256(results, p, cmp); + resultsFoundMask = Avx2.mm256_or_si256(resultsFoundMask, cmp); + + while (Hint.Likely(mm256_notalltrue_epi256(resultsFoundMask, elements))) + { + k = mm256_dec_epi64(k); + p = mm256_mullo_epi64(p, n, elements); + n = mm256_dec_epi64(n); + + cmp = Avx2.mm256_cmpeq_epi64(ZERO, k); + results = mm256_blendv_si256(results, p, cmp); + resultsFoundMask = Avx2.mm256_or_si256(resultsFoundMask, cmp); + } + + return results; + } + else throw new IllegalInstructionException(); + } + } + } + + + unsafe public static partial class maxmath + { + /// Returns the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 128 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt128 perm(UInt128 n, UInt128 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNotGreater(k, n); + + if (useFactorial.CountUnsafeLevels() > 0 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U128)) + { + if (useFactorial.CountUnsafeLevels() > 1 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U64)) + { + return factorial(n.lo64, Promise.NoOverflow) / factorial(n.lo64 - k.lo64, Promise.NoOverflow); + } + else + { + return factorial(n, Promise.NoOverflow) / factorial(n - k, Promise.NoOverflow); + } + } + + + if (Hint.Unlikely(k-- == 0)) + { + return 1; + } + else + { + UInt128 p = n--; + + while (Hint.Likely(k-- != 0)) + { + p *= n--; + } + + return p; + } + } + + /// Returns the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 128 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt128 perm(Int128 n, Int128 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsTrue(k >= 0); +Assert.IsTrue(n >= 0); + + return perm((UInt128)n, (UInt128)k, useFactorial); + } + + + /// Returns the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte perm(byte n, byte k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNotGreater(k, n); + + if (useFactorial.CountUnsafeLevels() > 0 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U64)) + { + if (useFactorial.CountUnsafeLevels() > 1 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U32)) + { + if (useFactorial.CountUnsafeLevels() > 2 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U16)) + { + if (useFactorial.CountUnsafeLevels() > 3 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U8)) + { + return (byte)(factorial(n, Promise.NoOverflow) / factorial((byte)(n - k), Promise.NoOverflow)); + } + else + { + return (byte)(factorial((ushort)n, Promise.NoOverflow) / factorial((ushort)(n - k), Promise.NoOverflow)); + } + } + else + { + return (byte)(factorial((uint)n, Promise.NoOverflow) / factorial((uint)(n - k), Promise.NoOverflow)); + } + } + else + { + return (byte)(factorial((ulong)n, Promise.NoOverflow) / factorial((ulong)(n - k), Promise.NoOverflow)); + } + } + + + return (byte)perm((uint)n, (uint)k); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte2 perm(byte2 n, byte2 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.perm_epu8(n, k, unsafeLevels: useFactorial.CountUnsafeLevels(), elements: 2); + } + else + { + return new byte2(perm(n.x, k.x, useFactorial), + perm(n.y, k.y, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte3 perm(byte3 n, byte3 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.perm_epu8(n, k, unsafeLevels: useFactorial.CountUnsafeLevels(), elements: 3); + } + else + { + return new byte3(perm(n.x, k.x, useFactorial), + perm(n.y, k.y, useFactorial), + perm(n.z, k.z, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte4 perm(byte4 n, byte4 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.perm_epu8(n, k, unsafeLevels: useFactorial.CountUnsafeLevels(), elements: 4); + } + else + { + return new byte4(perm(n.x, k.x, useFactorial), + perm(n.y, k.y, useFactorial), + perm(n.z, k.z, useFactorial), + perm(n.w, k.w, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte8 perm(byte8 n, byte8 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.perm_epu8(n, k, unsafeLevels: useFactorial.CountUnsafeLevels(), elements: 8); + } + else + { + return new byte8(perm(n.x0, k.x0, useFactorial), + perm(n.x1, k.x1, useFactorial), + perm(n.x2, k.x2, useFactorial), + perm(n.x3, k.x3, useFactorial), + perm(n.x4, k.x4, useFactorial), + perm(n.x5, k.x5, useFactorial), + perm(n.x6, k.x6, useFactorial), + perm(n.x7, k.x7, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte16 perm(byte16 n, byte16 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.perm_epu8(n, k, unsafeLevels: useFactorial.CountUnsafeLevels(), elements: 16); + } + else + { + return new byte16(perm(n.x0, k.x0, useFactorial), + perm(n.x1, k.x1, useFactorial), + perm(n.x2, k.x2, useFactorial), + perm(n.x3, k.x3, useFactorial), + perm(n.x4, k.x4, useFactorial), + perm(n.x5, k.x5, useFactorial), + perm(n.x6, k.x6, useFactorial), + perm(n.x7, k.x7, useFactorial), + perm(n.x8, k.x8, useFactorial), + perm(n.x9, k.x9, useFactorial), + perm(n.x10, k.x10, useFactorial), + perm(n.x11, k.x11, useFactorial), + perm(n.x12, k.x12, useFactorial), + perm(n.x13, k.x13, useFactorial), + perm(n.x14, k.x14, useFactorial), + perm(n.x15, k.x15, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte32 perm(byte32 n, byte32 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_perm_epu8(n, k, unsafeLevels: useFactorial.CountUnsafeLevels()); + } + else + { + return new byte32(perm(n.v16_0, k.v16_0, useFactorial), perm(n.v16_16, k.v16_16, useFactorial)); + } + } + + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte perm(sbyte n, sbyte k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(n); +Assert.IsNonNegative(k); + + return perm((byte)n, (byte)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte2 perm(sbyte2 n, sbyte2 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(n.x); +Assert.IsNonNegative(n.y); +Assert.IsNonNegative(k.x); +Assert.IsNonNegative(k.y); + + return perm((byte2)n, (byte2)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte3 perm(sbyte3 n, sbyte3 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(n.x); +Assert.IsNonNegative(n.y); +Assert.IsNonNegative(n.z); +Assert.IsNonNegative(k.x); +Assert.IsNonNegative(k.y); +Assert.IsNonNegative(k.z); + + return perm((byte3)n, (byte3)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte4 perm(sbyte4 n, sbyte4 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(n.x); +Assert.IsNonNegative(n.y); +Assert.IsNonNegative(n.z); +Assert.IsNonNegative(n.w); +Assert.IsNonNegative(k.x); +Assert.IsNonNegative(k.y); +Assert.IsNonNegative(k.z); +Assert.IsNonNegative(k.w); + + return perm((byte4)n, (byte4)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte8 perm(sbyte8 n, sbyte8 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(n.x0); +Assert.IsNonNegative(n.x1); +Assert.IsNonNegative(n.x2); +Assert.IsNonNegative(n.x3); +Assert.IsNonNegative(n.x4); +Assert.IsNonNegative(n.x5); +Assert.IsNonNegative(n.x6); +Assert.IsNonNegative(n.x7); +Assert.IsNonNegative(k.x0); +Assert.IsNonNegative(k.x1); +Assert.IsNonNegative(k.x2); +Assert.IsNonNegative(k.x3); +Assert.IsNonNegative(k.x4); +Assert.IsNonNegative(k.x5); +Assert.IsNonNegative(k.x6); +Assert.IsNonNegative(k.x7); + + return perm((byte8)n, (byte8)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte16 perm(sbyte16 n, sbyte16 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(n.x0); +Assert.IsNonNegative(n.x1); +Assert.IsNonNegative(n.x2); +Assert.IsNonNegative(n.x3); +Assert.IsNonNegative(n.x4); +Assert.IsNonNegative(n.x5); +Assert.IsNonNegative(n.x6); +Assert.IsNonNegative(n.x7); +Assert.IsNonNegative(n.x8); +Assert.IsNonNegative(n.x9); +Assert.IsNonNegative(n.x10); +Assert.IsNonNegative(n.x11); +Assert.IsNonNegative(n.x12); +Assert.IsNonNegative(n.x13); +Assert.IsNonNegative(n.x14); +Assert.IsNonNegative(n.x15); +Assert.IsNonNegative(k.x0); +Assert.IsNonNegative(k.x1); +Assert.IsNonNegative(k.x2); +Assert.IsNonNegative(k.x3); +Assert.IsNonNegative(k.x4); +Assert.IsNonNegative(k.x5); +Assert.IsNonNegative(k.x6); +Assert.IsNonNegative(k.x7); +Assert.IsNonNegative(k.x8); +Assert.IsNonNegative(k.x9); +Assert.IsNonNegative(k.x10); +Assert.IsNonNegative(k.x11); +Assert.IsNonNegative(k.x12); +Assert.IsNonNegative(k.x13); +Assert.IsNonNegative(k.x14); +Assert.IsNonNegative(k.x15); + + return perm((byte16)n, (byte16)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte32 perm(sbyte32 n, sbyte32 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(n.x0); +Assert.IsNonNegative(n.x1); +Assert.IsNonNegative(n.x2); +Assert.IsNonNegative(n.x3); +Assert.IsNonNegative(n.x4); +Assert.IsNonNegative(n.x5); +Assert.IsNonNegative(n.x6); +Assert.IsNonNegative(n.x7); +Assert.IsNonNegative(n.x8); +Assert.IsNonNegative(n.x9); +Assert.IsNonNegative(n.x10); +Assert.IsNonNegative(n.x11); +Assert.IsNonNegative(n.x12); +Assert.IsNonNegative(n.x13); +Assert.IsNonNegative(n.x14); +Assert.IsNonNegative(n.x15); +Assert.IsNonNegative(n.x16); +Assert.IsNonNegative(n.x17); +Assert.IsNonNegative(n.x18); +Assert.IsNonNegative(n.x19); +Assert.IsNonNegative(n.x20); +Assert.IsNonNegative(n.x21); +Assert.IsNonNegative(n.x22); +Assert.IsNonNegative(n.x23); +Assert.IsNonNegative(n.x24); +Assert.IsNonNegative(n.x25); +Assert.IsNonNegative(n.x26); +Assert.IsNonNegative(n.x27); +Assert.IsNonNegative(n.x28); +Assert.IsNonNegative(n.x29); +Assert.IsNonNegative(n.x30); +Assert.IsNonNegative(n.x31); +Assert.IsNonNegative(k.x0); +Assert.IsNonNegative(k.x1); +Assert.IsNonNegative(k.x2); +Assert.IsNonNegative(k.x3); +Assert.IsNonNegative(k.x4); +Assert.IsNonNegative(k.x5); +Assert.IsNonNegative(k.x6); +Assert.IsNonNegative(k.x7); +Assert.IsNonNegative(k.x8); +Assert.IsNonNegative(k.x9); +Assert.IsNonNegative(k.x10); +Assert.IsNonNegative(k.x11); +Assert.IsNonNegative(k.x12); +Assert.IsNonNegative(k.x13); +Assert.IsNonNegative(k.x14); +Assert.IsNonNegative(k.x15); +Assert.IsNonNegative(k.x16); +Assert.IsNonNegative(k.x17); +Assert.IsNonNegative(k.x18); +Assert.IsNonNegative(k.x19); +Assert.IsNonNegative(k.x20); +Assert.IsNonNegative(k.x21); +Assert.IsNonNegative(k.x22); +Assert.IsNonNegative(k.x23); +Assert.IsNonNegative(k.x24); +Assert.IsNonNegative(k.x25); +Assert.IsNonNegative(k.x26); +Assert.IsNonNegative(k.x27); +Assert.IsNonNegative(k.x28); +Assert.IsNonNegative(k.x29); +Assert.IsNonNegative(k.x30); +Assert.IsNonNegative(k.x31); + + return perm((byte32)n, (byte32)k, useFactorial); + } + + + /// Returns the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort perm(ushort n, ushort k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNotGreater(k, n); + + if (useFactorial.CountUnsafeLevels() > 0 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U64)) + { + if (useFactorial.CountUnsafeLevels() > 1 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U32)) + { + if (useFactorial.CountUnsafeLevels() > 2 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U16)) + { + return (ushort)(factorial(n, Promise.NoOverflow) / factorial((ushort)(n - k), Promise.NoOverflow)); + } + else + { + return (ushort)(factorial((uint)n, Promise.NoOverflow) / factorial((uint)(n - k), Promise.NoOverflow)); + } + } + else + { + return (ushort)(factorial((ulong)n, Promise.NoOverflow) / factorial((ulong)(n - k), Promise.NoOverflow)); + } + } + + + return (ushort)perm((uint)n, (uint)k); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort2 perm(ushort2 n, ushort2 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.perm_epu16(n, k, unsafeLevels: useFactorial.CountUnsafeLevels(), elements: 2); + } + else + { + return new ushort2(perm(n.x, k.x, useFactorial), + perm(n.y, k.y, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort3 perm(ushort3 n, ushort3 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.perm_epu16(n, k, unsafeLevels: useFactorial.CountUnsafeLevels(), elements: 3); + } + else + { + return new ushort3(perm(n.x, k.x, useFactorial), + perm(n.y, k.y, useFactorial), + perm(n.z, k.z, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort4 perm(ushort4 n, ushort4 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.perm_epu16(n, k, unsafeLevels: useFactorial.CountUnsafeLevels(), elements: 4); + } + else + { + return new ushort4(perm(n.x, k.x, useFactorial), + perm(n.y, k.y, useFactorial), + perm(n.z, k.z, useFactorial), + perm(n.w, k.w, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort8 perm(ushort8 n, ushort8 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.perm_epu16(n, k, unsafeLevels: useFactorial.CountUnsafeLevels(), elements: 8); + } + else + { + return new ushort8(perm(n.x0, k.x0, useFactorial), + perm(n.x1, k.x1, useFactorial), + perm(n.x2, k.x2, useFactorial), + perm(n.x3, k.x3, useFactorial), + perm(n.x4, k.x4, useFactorial), + perm(n.x5, k.x5, useFactorial), + perm(n.x6, k.x6, useFactorial), + perm(n.x7, k.x7, useFactorial)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort16 perm(ushort16 n, ushort16 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_perm_epu16(n, k, unsafeLevels: useFactorial.CountUnsafeLevels()); + } + else + { + return new ushort16(perm(n.v8_0, k.v8_0, useFactorial), perm(n.v8_8, k.v8_8, useFactorial)); + } + } + + + /// Returns the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort perm(short n, short k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(n); +Assert.IsNonNegative(k); + + return perm((ushort)n, (ushort)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort2 perm(short2 n, short2 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(n.x); +Assert.IsNonNegative(n.y); +Assert.IsNonNegative(k.x); +Assert.IsNonNegative(k.y); + + return perm((ushort2)n, (ushort2)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort3 perm(short3 n, short3 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(n.x); +Assert.IsNonNegative(n.y); +Assert.IsNonNegative(n.z); +Assert.IsNonNegative(k.x); +Assert.IsNonNegative(k.y); +Assert.IsNonNegative(k.z); + + return perm((ushort3)n, (ushort3)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort4 perm(short4 n, short4 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(n.x); +Assert.IsNonNegative(n.y); +Assert.IsNonNegative(n.z); +Assert.IsNonNegative(n.w); +Assert.IsNonNegative(k.x); +Assert.IsNonNegative(k.y); +Assert.IsNonNegative(k.z); +Assert.IsNonNegative(k.w); + + return perm((ushort4)n, (ushort4)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort8 perm(short8 n, short8 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(n.x0); +Assert.IsNonNegative(n.x1); +Assert.IsNonNegative(n.x2); +Assert.IsNonNegative(n.x3); +Assert.IsNonNegative(n.x4); +Assert.IsNonNegative(n.x5); +Assert.IsNonNegative(n.x6); +Assert.IsNonNegative(n.x7); +Assert.IsNonNegative(k.x0); +Assert.IsNonNegative(k.x1); +Assert.IsNonNegative(k.x2); +Assert.IsNonNegative(k.x3); +Assert.IsNonNegative(k.x4); +Assert.IsNonNegative(k.x5); +Assert.IsNonNegative(k.x6); +Assert.IsNonNegative(k.x7); + + return perm((ushort8)n, (ushort8)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 16 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 8 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort16 perm(short16 n, short16 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(n.x0); +Assert.IsNonNegative(n.x1); +Assert.IsNonNegative(n.x2); +Assert.IsNonNegative(n.x3); +Assert.IsNonNegative(n.x4); +Assert.IsNonNegative(n.x5); +Assert.IsNonNegative(n.x6); +Assert.IsNonNegative(n.x7); +Assert.IsNonNegative(n.x8); +Assert.IsNonNegative(n.x9); +Assert.IsNonNegative(n.x10); +Assert.IsNonNegative(n.x11); +Assert.IsNonNegative(n.x12); +Assert.IsNonNegative(n.x13); +Assert.IsNonNegative(n.x14); +Assert.IsNonNegative(n.x15); +Assert.IsNonNegative(k.x0); +Assert.IsNonNegative(k.x1); +Assert.IsNonNegative(k.x2); +Assert.IsNonNegative(k.x3); +Assert.IsNonNegative(k.x4); +Assert.IsNonNegative(k.x5); +Assert.IsNonNegative(k.x6); +Assert.IsNonNegative(k.x7); +Assert.IsNonNegative(k.x8); +Assert.IsNonNegative(k.x9); +Assert.IsNonNegative(k.x10); +Assert.IsNonNegative(k.x11); +Assert.IsNonNegative(k.x12); +Assert.IsNonNegative(k.x13); +Assert.IsNonNegative(k.x14); +Assert.IsNonNegative(k.x15); + + return perm((ushort16)n, (ushort16)k, useFactorial); + } + + + /// Returns the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 128 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint perm(uint n, uint k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNotGreater(k, n); + + if (useFactorial.CountUnsafeLevels() > 0 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U128)) + { + if (useFactorial.CountUnsafeLevels() > 1 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U64)) + { + return (uint)(factorial((ulong)n, Promise.NoOverflow) / factorial((ulong)(n - k), Promise.NoOverflow)); + } + else + { + return (uint)(factorial((UInt128)n, Promise.NoOverflow) / factorial((UInt128)(n - k), Promise.NoOverflow)); + } + } + + + if (Hint.Unlikely(k-- == 0)) + { + return 1; + } + else + { + uint p = n--; + + while (Hint.Likely(k-- != 0)) + { + p *= n--; + } + + return p; + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint2 perm(uint2 n, uint2 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt2(Xse.perm_epu32(RegisterConversion.ToV128(n), RegisterConversion.ToV128(k), unsafeLevels: useFactorial.CountUnsafeLevels(), elements: 2)); + } + else + { + return new uint2(perm(n.x, k.x, useFactorial.CountUnsafeLevels() != 0 ? Promise.Unsafe1 : Promise.Nothing), + perm(n.y, k.y, useFactorial.CountUnsafeLevels() != 0 ? Promise.Unsafe1 : Promise.Nothing)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint3 perm(uint3 n, uint3 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt3(Xse.perm_epu32(RegisterConversion.ToV128(n), RegisterConversion.ToV128(k), unsafeLevels: useFactorial.CountUnsafeLevels(), elements: 3)); + } + else + { + return new uint3(perm(n.x, k.x, useFactorial.CountUnsafeLevels() != 0 ? Promise.Unsafe1 : Promise.Nothing), + perm(n.y, k.y, useFactorial.CountUnsafeLevels() != 0 ? Promise.Unsafe1 : Promise.Nothing), + perm(n.z, k.z, useFactorial.CountUnsafeLevels() != 0 ? Promise.Unsafe1 : Promise.Nothing)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint4 perm(uint4 n, uint4 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt4(Xse.perm_epu32(RegisterConversion.ToV128(n), RegisterConversion.ToV128(k), unsafeLevels: useFactorial.CountUnsafeLevels(), elements: 4)); + } + else + { + return new uint4(perm(n.x, k.x, useFactorial.CountUnsafeLevels() != 0 ? Promise.Unsafe1 : Promise.Nothing), + perm(n.y, k.y, useFactorial.CountUnsafeLevels() != 0 ? Promise.Unsafe1 : Promise.Nothing), + perm(n.z, k.z, useFactorial.CountUnsafeLevels() != 0 ? Promise.Unsafe1 : Promise.Nothing), + perm(n.w, k.w, useFactorial.CountUnsafeLevels() != 0 ? Promise.Unsafe1 : Promise.Nothing)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint8 perm(uint8 n, uint8 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_perm_epu32(n, k, unsafeLevels: useFactorial.CountUnsafeLevels()); + } + else + { + return new uint8(perm(n.v4_0, k.v4_0, useFactorial), perm(n.v4_4, k.v4_4, useFactorial)); + } + } + + + /// Returns the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 128 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint perm(int n, int k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(k); +Assert.IsNonNegative(n); + + return perm((uint)n, (uint)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint2 perm(int2 n, int2 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(k.x); +Assert.IsNonNegative(k.y); +Assert.IsNonNegative(n.x); +Assert.IsNonNegative(n.y); + + return perm((uint2)n, (uint2)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint3 perm(int3 n, int3 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(k.x); +Assert.IsNonNegative(k.y); +Assert.IsNonNegative(k.z); +Assert.IsNonNegative(n.x); +Assert.IsNonNegative(n.y); +Assert.IsNonNegative(n.z); + + return perm((uint3)n, (uint3)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint4 perm(int4 n, int4 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(k.x); +Assert.IsNonNegative(k.y); +Assert.IsNonNegative(k.z); +Assert.IsNonNegative(k.w); +Assert.IsNonNegative(n.x); +Assert.IsNonNegative(n.y); +Assert.IsNonNegative(n.z); +Assert.IsNonNegative(n.w); + + return perm((uint4)n, (uint4)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint8 perm(int8 n, int8 k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(k.x0); +Assert.IsNonNegative(k.x1); +Assert.IsNonNegative(k.x2); +Assert.IsNonNegative(k.x3); +Assert.IsNonNegative(k.x4); +Assert.IsNonNegative(k.x5); +Assert.IsNonNegative(k.x6); +Assert.IsNonNegative(k.x7); +Assert.IsNonNegative(n.x0); +Assert.IsNonNegative(n.x1); +Assert.IsNonNegative(n.x2); +Assert.IsNonNegative(n.x3); +Assert.IsNonNegative(n.x4); +Assert.IsNonNegative(n.x5); +Assert.IsNonNegative(n.x6); +Assert.IsNonNegative(n.x7); + + return perm((uint8)n, (uint8)k, useFactorial); + } + + + /// Returns the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 128 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong perm(ulong n, ulong k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNotGreater(k, n); + + if (useFactorial.CountUnsafeLevels() > 0 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U128)) + { + if (useFactorial.CountUnsafeLevels() > 1 || Xse.constexpr.IS_TRUE(n <= MAX_INVERSE_FACTORIAL_U64)) + { + return factorial(n, Promise.NoOverflow) / factorial(n - k, Promise.NoOverflow); + } + else + { + return (ulong)(factorial((UInt128)n, Promise.NoOverflow) / factorial((UInt128)(n - k), Promise.NoOverflow)); + } + } + + + if (Hint.Unlikely(k-- == 0)) + { + return 1; + } + else + { + ulong p = n--; + + while (Hint.Likely(k-- != 0)) + { + p *= n--; + } + + return p; + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong2 perm(ulong2 n, ulong2 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.perm_epu64(n, k, unsafeLevels: useFactorial.CountUnsafeLevels()); + } + else + { + return new ulong2(perm(n.x, k.x, useFactorial.CountUnsafeLevels() != 0 ? Promise.Unsafe1 : Promise.Nothing), + perm(n.y, k.y, useFactorial.CountUnsafeLevels() != 0 ? Promise.Unsafe1 : Promise.Nothing)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong3 perm(ulong3 n, ulong3 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_perm_epu64(n, k, unsafeLevels: useFactorial.CountUnsafeLevels(), elements: 3); + } + else + { + return new ulong3(perm(n.xy, k.xy, useFactorial), + perm(n.z, k.z, useFactorial.CountUnsafeLevels() != 0 ? Promise.Unsafe1 : Promise.Nothing)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong4 perm(ulong4 n, ulong4 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_perm_epu64(n, k, unsafeLevels: useFactorial.CountUnsafeLevels(), elements: 4); + } + else + { + return new ulong4(perm(n.xy, k.xy, useFactorial), + perm(n.zw, k.zw, useFactorial)); + } + } + + + /// Returns the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 128 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong perm(long n, long k, Promise useFactorial = Promise.Nothing) + { +Assert.IsNonNegative(k); +Assert.IsNonNegative(n); + + return perm((ulong)n, (ulong)k, useFactorial); + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong2 perm(long2 n, long2 k, Promise useFactorial = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { +Assert.IsNonNegative(k.x); +Assert.IsNonNegative(k.y); +Assert.IsNonNegative(n.x); +Assert.IsNonNegative(n.y); + + return Xse.perm_epu64(n, k, unsafeLevels: useFactorial.CountUnsafeLevels()); + } + else + { + return new ulong2(perm(n.x, k.x, useFactorial.CountUnsafeLevels() != 0 ? Promise.Unsafe1 : Promise.Nothing), + perm(n.y, k.y, useFactorial.CountUnsafeLevels() != 0 ? Promise.Unsafe1 : Promise.Nothing)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong3 perm(long3 n, long3 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { +Assert.IsNonNegative(k.x); +Assert.IsNonNegative(k.y); +Assert.IsNonNegative(k.z); +Assert.IsNonNegative(n.x); +Assert.IsNonNegative(n.y); +Assert.IsNonNegative(n.z); + + return Xse.mm256_perm_epu64(n, k, unsafeLevels: useFactorial.CountUnsafeLevels(), elements: 3); + } + else + { + return new ulong3(perm(n.xy, k.xy, useFactorial), + perm(n.z, k.z, useFactorial.CountUnsafeLevels() != 0 ? Promise.Unsafe1 : Promise.Nothing)); + } + } + + /// Returns for each pair of corresponding components the number of ways to choose items from items without repetition and with order. Also known as "-permutations of ". + /// + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 64 bit overflow. + /// A '' with its flag set may cause a memory access violation for any ! that result in an unsigned 32 bit overflow. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong4 perm(long4 n, long4 k, Promise useFactorial = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { +Assert.IsNonNegative(k.x); +Assert.IsNonNegative(k.y); +Assert.IsNonNegative(k.z); +Assert.IsNonNegative(k.w); +Assert.IsNonNegative(n.x); +Assert.IsNonNegative(n.y); +Assert.IsNonNegative(n.z); +Assert.IsNonNegative(n.w); + + return Xse.mm256_perm_epu64(n, k, unsafeLevels: useFactorial.CountUnsafeLevels(), elements: 4); + } + else + { + return new ulong4(perm(n.xy, k.xy, useFactorial), + perm(n.zw, k.zw, useFactorial)); + } + } + } +} \ No newline at end of file diff --git a/Tests/Editor/Testing Tools.cs.meta b/Runtime/Math Lib/Functions/Arithmetic/Integer/k-permutations of n.cs.meta similarity index 83% rename from Tests/Editor/Testing Tools.cs.meta rename to Runtime/Math Lib/Functions/Arithmetic/Integer/k-permutations of n.cs.meta index 352ae19..8dc180b 100644 --- a/Tests/Editor/Testing Tools.cs.meta +++ b/Runtime/Math Lib/Functions/Arithmetic/Integer/k-permutations of n.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b9da01bff00a69e47953de66b0c760cb +guid: 126706513ceea4640acc7beced516d77 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Runtime/Math Lib/Functions/Arithmetic/Next Greater.cs b/Runtime/Math Lib/Functions/Arithmetic/Next Greater.cs new file mode 100644 index 0000000..56ec156 --- /dev/null +++ b/Runtime/Math Lib/Functions/Arithmetic/Next Greater.cs @@ -0,0 +1,1714 @@ +using System.Runtime.CompilerServices; +using Unity.Burst.Intrinsics; +using Unity.Mathematics; +using MaxMath.Intrinsics; + +using static Unity.Burst.Intrinsics.X86; +using static MaxMath.LUT.FLOATING_POINT; + +namespace MaxMath +{ + namespace Intrinsics + { + unsafe public static partial class Xse + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 inc_pq(v128 a, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + //promiseNonZero |= constexpr.ALL_NEQ_PQ(a, 0f, elements); + //promisePositive |= constexpr.ALL_GT_PQ(a, 0f, elements); + //promiseNegative |= constexpr.ALL_LT_PQ(a, 0f, elements); + //promiseNotNanInf |= constexpr.ALL_NOTNAN_PQ(a, elements) && constexpr.ALL_NEQ_PQ(a, quarter.PositiveInfinity, elements) && constexpr.ALL_NEQ_PH(a, quarter.NegativeInfinity, elements); + + v128 summand; + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = setall_si128(); + } + else + { + v128 ONE = Sse2.set1_epi8(1); + + if (Sse4_1.IsSse41Supported) + { + summand = Sse4_1.blendv_epi8(ONE, setall_si128(), a); + } + else + { + summand = Sse2.or_si128(srai_epi8(a, 7), ONE); + } + } + } + else + { + v128 ONE = Sse2.set1_epi8(1); + v128 NEGATIVE_ZERO = Sse2.set1_epi8(unchecked((sbyte)(1 << 7))); + + v128 negative0 = Sse2.cmpeq_epi8(a, NEGATIVE_ZERO); + summand = ternarylogic_si128(negative0, srai_epi8(a, 7), ONE, TernaryOperation.OxAE); + a = Sse2.andnot_si128(negative0, a); + } + + if (!promiseNotNanInf) + { + v128 SIGNALING_EXPONENT = Sse2.set1_epi8(quarter.SIGNALING_EXPONENT); + + v128 nanInf = Sse2.cmpeq_epi8(SIGNALING_EXPONENT, Sse2.and_si128(a, SIGNALING_EXPONENT)); + summand = Sse2.andnot_si128(nanInf, summand); + } + + if (promisePositive) + { + return Sse2.sub_epi8(a, summand); + } + else + { + return Sse2.add_epi8(a, summand); + } + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 inc_ph(v128 a, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + //promiseNonZero |= constexpr.ALL_NEQ_PH(a, 0f, elements); + //promisePositive |= constexpr.ALL_GT_PH(a, 0f, elements); + //promiseNegative |= constexpr.ALL_LT_PH(a, 0f, elements); + //promiseNotNanInf |= constexpr.ALL_NOTNAN_PH(a, elements) && constexpr.ALL_NEQ_PH(a, (half)float.PositiveInfinity, elements) && constexpr.ALL_NEQ_PH(a, (half)float.NegativeInfinity, elements); + + v128 summand; + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = setall_si128(); + } + else + { + v128 ONE = Sse2.set1_epi16(1); + + summand = Sse2.or_si128(Sse2.srai_epi16(a, 15), ONE); + } + } + else + { + v128 ONE = Sse2.set1_epi16(1); + v128 NEGATIVE_ZERO = Sse2.set1_epi16(unchecked((short)(1 << 15))); + + v128 negative0 = Sse2.cmpeq_epi16(a, NEGATIVE_ZERO); + summand = ternarylogic_si128(negative0, Sse2.srai_epi16(a, 15), ONE, TernaryOperation.OxAE); + a = Sse2.andnot_si128(negative0, a); + } + + if (!promiseNotNanInf) + { + v128 SIGNALING_EXPONENT = Sse2.set1_epi16((short)F16_SIGNALING_EXPONENT); + + v128 nanInf = Sse2.cmpeq_epi16(SIGNALING_EXPONENT, Sse2.and_si128(a, SIGNALING_EXPONENT)); + summand = Sse2.andnot_si128(nanInf, summand); + } + + if (promisePositive) + { + return Sse2.sub_epi16(a, summand); + } + else + { + return Sse2.add_epi16(a, summand); + } + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 inc_ps(v128 a, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false, byte elements = 4) + { + if (Sse2.IsSse2Supported) + { + promiseNonZero |= constexpr.ALL_NEQ_PS(a, 0f, elements); + promisePositive |= constexpr.ALL_GT_PS(a, 0f, elements); + promiseNegative |= constexpr.ALL_LT_PS(a, 0f, elements); + promiseNotNanInf |= constexpr.ALL_NOTNAN_PS(a, elements) && constexpr.ALL_NEQ_PS(a, float.PositiveInfinity, elements) && constexpr.ALL_NEQ_PS(a, float.NegativeInfinity, elements); + + v128 summand; + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = setall_si128(); + } + else + { + v128 ONE = Sse2.set1_epi32(1); + + if (Sse4_1.IsSse41Supported) + { + summand = Sse4_1.blendv_ps(ONE, setall_si128(), a); + } + else + { + summand = Sse2.or_si128(Sse2.srai_epi32(a, 31), ONE); + } + } + } + else + { + v128 ONE = Sse2.set1_epi32(1); + v128 NEGATIVE_ZERO = Sse2.set1_epi32(1 << 31); + + v128 negative0 = Sse2.cmpeq_epi32(a, NEGATIVE_ZERO); + summand = ternarylogic_si128(negative0, Sse2.srai_epi32(a, 31), ONE, TernaryOperation.OxAE); + a = Sse2.andnot_si128(negative0, a); + } + + if (!promiseNotNanInf) + { + v128 SIGNALING_EXPONENT = Sse2.set1_epi32(F32_SIGNALING_EXPONENT); + + v128 nanInf = Sse2.cmpeq_epi32(SIGNALING_EXPONENT, Sse2.and_si128(a, SIGNALING_EXPONENT)); + summand = Sse2.andnot_si128(nanInf, summand); + } + + if (promisePositive) + { + return Sse2.sub_epi32(a, summand); + } + else + { + return Sse2.add_epi32(a, summand); + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_inc_ps(v256 a, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false) + { + if (Avx2.IsAvx2Supported) + { + promiseNonZero |= constexpr.ALL_NEQ_PS(a, 0f); + promisePositive |= constexpr.ALL_GT_PS(a, 0f); + promiseNegative |= constexpr.ALL_LT_PS(a, 0f); + promiseNotNanInf |= constexpr.ALL_NOTNAN_PS(a) && constexpr.ALL_NEQ_PS(a, float.PositiveInfinity) && constexpr.ALL_NEQ_PS(a, float.NegativeInfinity); + + v256 summand; + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = mm256_setall_si256(); + } + else + { + v256 ONE = Avx.mm256_set1_epi32(1); + + summand = Avx.mm256_blendv_ps(ONE, mm256_setall_si256(), a); + } + } + else + { + v256 ONE = Avx.mm256_set1_epi32(1); + v256 NEGATIVE_ZERO = Avx.mm256_set1_epi32(1 << 31); + + v256 negative0 = Avx2.mm256_cmpeq_epi32(a, NEGATIVE_ZERO); + summand = mm256_ternarylogic_si256(negative0, Avx2.mm256_srai_epi32(a, 31), ONE, TernaryOperation.OxAE); + a = Avx2.mm256_andnot_si256(negative0, a); + } + + if (!promiseNotNanInf) + { + v256 SIGNALING_EXPONENT = Avx.mm256_set1_epi32(F32_SIGNALING_EXPONENT); + + v256 nanInf = Avx2.mm256_cmpeq_epi32(SIGNALING_EXPONENT, Avx2.mm256_and_si256(a, SIGNALING_EXPONENT)); + summand = Avx2.mm256_andnot_si256(nanInf, summand); + } + + if (promisePositive) + { + return Avx2.mm256_sub_epi32(a, summand); + } + else + { + return Avx2.mm256_add_epi32(a, summand); + } + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 inc_pd(v128 a, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false) + { + if (Sse2.IsSse2Supported) + { + promiseNonZero |= constexpr.ALL_NEQ_PD(a, 0d); + promisePositive |= constexpr.ALL_GT_PD(a, 0d); + promiseNegative |= constexpr.ALL_LT_PD(a, 0d); + promiseNotNanInf |= constexpr.ALL_NOTNAN_PD(a) && constexpr.ALL_NEQ_PD(a, double.PositiveInfinity) && constexpr.ALL_NEQ_PD(a, double.NegativeInfinity); + + v128 summand; + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = setall_si128(); + } + else + { + v128 ONE = Sse2.set1_epi64x(1); + + if (Sse4_1.IsSse41Supported) + { + summand = Sse4_1.blendv_pd(ONE, setall_si128(), a); + } + else + { + summand = Sse2.or_si128(srai_epi64(a, 63), ONE); + } + } + } + else + { + v128 ONE = Sse2.set1_epi64x(1); + v128 NEGATIVE_ZERO = Sse2.set1_epi64x(1L << 63); + + v128 negative0 = cmpeq_epi64(a, NEGATIVE_ZERO); + summand = ternarylogic_si128(negative0, srai_epi64(a, 63), ONE, TernaryOperation.OxAE); + a = Sse2.andnot_si128(negative0, a); + } + + if (!promiseNotNanInf) + { + v128 SIGNALING_EXPONENT = Sse2.set1_epi64x(F64_SIGNALING_EXPONENT); + + v128 nanInf; + if (Sse4_1.IsSse41Supported) + { + nanInf = Sse4_1.cmpeq_epi64(SIGNALING_EXPONENT, Sse2.and_si128(a, SIGNALING_EXPONENT)); + } + else + { + nanInf = Sse2.shuffle_epi32(Sse2.cmpeq_epi32(SIGNALING_EXPONENT, Sse2.and_si128(a, SIGNALING_EXPONENT)), Sse.SHUFFLE(3, 3, 1, 1)); + } + + summand = Sse2.andnot_si128(nanInf, summand); + } + + if (promisePositive) + { + return Sse2.sub_epi64(a, summand); + } + else + { + return Sse2.add_epi64(a, summand); + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_inc_pd(v256 a, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false, byte elements = 4) + { + if (Avx2.IsAvx2Supported) + { + promiseNonZero |= constexpr.ALL_NEQ_PD(a, 0d, elements); + promisePositive |= constexpr.ALL_GT_PD(a, 0d, elements); + promiseNegative |= constexpr.ALL_LT_PD(a, 0d, elements); + promiseNotNanInf |= constexpr.ALL_NOTNAN_PD(a, elements) && constexpr.ALL_NEQ_PD(a, double.PositiveInfinity, elements) && constexpr.ALL_NEQ_PD(a, double.NegativeInfinity, elements); + + v256 summand; + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = mm256_setall_si256(); + } + else + { + v256 ONE = Avx.mm256_set1_epi64x(1); + + summand = Avx.mm256_blendv_pd(ONE, mm256_setall_si256(), a); + } + } + else + { + v256 ONE = Avx.mm256_set1_epi64x(1); + v256 NEGATIVE_ZERO = Avx.mm256_set1_epi64x(1L << 63); + + v256 negative0 = Avx2.mm256_cmpeq_epi64(a, NEGATIVE_ZERO); + summand = mm256_ternarylogic_si256(negative0, mm256_srai_epi64(a, 63), ONE, TernaryOperation.OxAE); + a = Avx2.mm256_andnot_si256(negative0, a); + } + + if (!promiseNotNanInf) + { + v256 SIGNALING_EXPONENT = Avx.mm256_set1_epi64x(F64_SIGNALING_EXPONENT); + + v256 nanInf = Avx2.mm256_cmpeq_epi64(SIGNALING_EXPONENT, Avx2.mm256_and_si256(a, SIGNALING_EXPONENT)); + summand = Avx2.mm256_andnot_si256(nanInf, summand); + } + + if (promisePositive) + { + return Avx2.mm256_sub_epi64(a, summand); + } + else + { + return Avx2.mm256_add_epi64(a, summand); + } + } + else throw new IllegalInstructionException(); + } + } + } + + + unsafe public static partial class maxmath + { + /// Returns the next closest greater than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt128 nextgreater(UInt128 x) + { + return x + tobyte(x != UInt128.MaxValue); + } + + + /// Returns the next closest greater than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Int128 nextgreater(Int128 x) + { + return x + tobyte(x != Int128.MaxValue); + } + + + /// Returns the next closest greater than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte nextgreater(byte x) + { + return (byte)(x + tobyte(x != byte.MaxValue)); + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte2 nextgreater(byte2 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epu8(x); + } + else + { + return new byte2(nextgreater(x.x), + nextgreater(x.y)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte3 nextgreater(byte3 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epu8(x); + } + else + { + return new byte3(nextgreater(x.x), + nextgreater(x.y), + nextgreater(x.z)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte4 nextgreater(byte4 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epu8(x); + } + else + { + return new byte4(nextgreater(x.x), + nextgreater(x.y), + nextgreater(x.z), + nextgreater(x.w)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte8 nextgreater(byte8 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epu8(x); + } + else + { + return new byte8(nextgreater(x.x0), + nextgreater(x.x1), + nextgreater(x.x2), + nextgreater(x.x3), + nextgreater(x.x4), + nextgreater(x.x5), + nextgreater(x.x6), + nextgreater(x.x7)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte16 nextgreater(byte16 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epu8(x); + } + else + { + return new byte16(nextgreater(x.x0), + nextgreater(x.x1), + nextgreater(x.x2), + nextgreater(x.x3), + nextgreater(x.x4), + nextgreater(x.x5), + nextgreater(x.x6), + nextgreater(x.x7), + nextgreater(x.x8), + nextgreater(x.x9), + nextgreater(x.x10), + nextgreater(x.x11), + nextgreater(x.x12), + nextgreater(x.x13), + nextgreater(x.x14), + nextgreater(x.x15)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte32 nextgreater(byte32 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_incs_epu8(x); + } + else + { + return new byte32(nextgreater(x.v16_0), + nextgreater(x.v16_16)); + } + } + + + /// Returns the next closest greater than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte nextgreater(sbyte x) + { + return (sbyte)(x + tosbyte(x != sbyte.MaxValue)); + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte2 nextgreater(sbyte2 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epi8(x); + } + else + { + return new sbyte2(nextgreater(x.x), + nextgreater(x.y)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte3 nextgreater(sbyte3 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epi8(x); + } + else + { + return new sbyte3(nextgreater(x.x), + nextgreater(x.y), + nextgreater(x.z)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte4 nextgreater(sbyte4 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epi8(x); + } + else + { + return new sbyte4(nextgreater(x.x), + nextgreater(x.y), + nextgreater(x.z), + nextgreater(x.w)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte8 nextgreater(sbyte8 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epi8(x); + } + else + { + return new sbyte8(nextgreater(x.x0), + nextgreater(x.x1), + nextgreater(x.x2), + nextgreater(x.x3), + nextgreater(x.x4), + nextgreater(x.x5), + nextgreater(x.x6), + nextgreater(x.x7)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte16 nextgreater(sbyte16 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epi8(x); + } + else + { + return new sbyte16(nextgreater(x.x0), + nextgreater(x.x1), + nextgreater(x.x2), + nextgreater(x.x3), + nextgreater(x.x4), + nextgreater(x.x5), + nextgreater(x.x6), + nextgreater(x.x7), + nextgreater(x.x8), + nextgreater(x.x9), + nextgreater(x.x10), + nextgreater(x.x11), + nextgreater(x.x12), + nextgreater(x.x13), + nextgreater(x.x14), + nextgreater(x.x15)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte32 nextgreater(sbyte32 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_incs_epi8(x); + } + else + { + return new sbyte32(nextgreater(x.v16_0), + nextgreater(x.v16_16)); + } + } + + + /// Returns the next closest greater than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort nextgreater(ushort x) + { + return (ushort)(x + tobyte(x != ushort.MaxValue)); + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort2 nextgreater(ushort2 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epu16(x); + } + else + { + return new ushort2(nextgreater(x.x), + nextgreater(x.y)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort3 nextgreater(ushort3 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epu16(x); + } + else + { + return new ushort3(nextgreater(x.x), + nextgreater(x.y), + nextgreater(x.z)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort4 nextgreater(ushort4 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epu16(x); + } + else + { + return new ushort4(nextgreater(x.x), + nextgreater(x.y), + nextgreater(x.z), + nextgreater(x.w)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort8 nextgreater(ushort8 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epu16(x); + } + else + { + return new ushort8(nextgreater(x.x0), + nextgreater(x.x1), + nextgreater(x.x2), + nextgreater(x.x3), + nextgreater(x.x4), + nextgreater(x.x5), + nextgreater(x.x6), + nextgreater(x.x7)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort16 nextgreater(ushort16 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_incs_epu16(x); + } + else + { + return new ushort16(nextgreater(x.v8_0), + nextgreater(x.v8_8)); + } + } + + + /// Returns the next closest greater than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short nextgreater(short x) + { + return (short)(x + tobyte(x != short.MaxValue)); + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short2 nextgreater(short2 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epi16(x); + } + else + { + return new short2(nextgreater(x.x), + nextgreater(x.y)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short3 nextgreater(short3 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epi16(x); + } + else + { + return new short3(nextgreater(x.x), + nextgreater(x.y), + nextgreater(x.z)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short4 nextgreater(short4 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epi16(x); + } + else + { + return new short4(nextgreater(x.x), + nextgreater(x.y), + nextgreater(x.z), + nextgreater(x.w)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short8 nextgreater(short8 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epi16(x); + } + else + { + return new short8(nextgreater(x.x0), + nextgreater(x.x1), + nextgreater(x.x2), + nextgreater(x.x3), + nextgreater(x.x4), + nextgreater(x.x5), + nextgreater(x.x6), + nextgreater(x.x7)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short16 nextgreater(short16 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_incs_epi16(x); + } + else + { + return new short16(nextgreater(x.v8_0), + nextgreater(x.v8_8)); + } + } + + + /// Returns the next closest greater than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint nextgreater(uint x) + { + return x + tobyte(x != uint.MaxValue); + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint2 nextgreater(uint2 x) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt2(Xse.incs_epu32(RegisterConversion.ToV128(x), 2)); + } + else + { + return new uint2(nextgreater(x.x), + nextgreater(x.y)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint3 nextgreater(uint3 x) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt3(Xse.incs_epu32(RegisterConversion.ToV128(x), 3)); + } + else + { + return new uint3(nextgreater(x.x), + nextgreater(x.y), + nextgreater(x.z)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint4 nextgreater(uint4 x) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt4(Xse.incs_epu32(RegisterConversion.ToV128(x), 4)); + } + else + { + return new uint4(nextgreater(x.x), + nextgreater(x.y), + nextgreater(x.z), + nextgreater(x.w)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint8 nextgreater(uint8 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_incs_epu32(x); + } + else + { + return new uint8(nextgreater(x.v4_0), + nextgreater(x.v4_4)); + } + } + + + /// Returns the next closest greater than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int nextgreater(int x) + { + return x + tobyte(x != int.MaxValue); + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int2 nextgreater(int2 x) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToInt2(Xse.incs_epi32(RegisterConversion.ToV128(x), 2)); + } + else + { + return new int2(nextgreater(x.x), + nextgreater(x.y)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int3 nextgreater(int3 x) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToInt3(Xse.incs_epi32(RegisterConversion.ToV128(x), 3)); + } + else + { + return new int3(nextgreater(x.x), + nextgreater(x.y), + nextgreater(x.z)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int4 nextgreater(int4 x) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToInt4(Xse.incs_epi32(RegisterConversion.ToV128(x), 4)); + } + else + { + return new int4(nextgreater(x.x), + nextgreater(x.y), + nextgreater(x.z), + nextgreater(x.w)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int8 nextgreater(int8 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_incs_epi32(x); + } + else + { + return new int8(nextgreater(x.v4_0), + nextgreater(x.v4_4)); + } + } + + + /// Returns the next closest greater than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong nextgreater(ulong x) + { + return x + tobyte(x != ulong.MaxValue); + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong2 nextgreater(ulong2 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epu64(x); + } + else + { + return new ulong2(nextgreater(x.x), + nextgreater(x.y)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong3 nextgreater(ulong3 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_incs_epu64(x, 3); + } + else + { + return new ulong3(nextgreater(x.xy), + nextgreater(x.z)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong4 nextgreater(ulong4 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_incs_epu64(x, 4); + } + else + { + return new ulong4(nextgreater(x.xy), + nextgreater(x.zw)); + } + } + + + /// Returns the next closest greater than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long nextgreater(long x) + { + return x + tobyte(x != long.MaxValue); + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long2 nextgreater(long2 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.incs_epi64(x); + } + else + { + return new long2(nextgreater(x.x), + nextgreater(x.y)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long3 nextgreater(long3 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_incs_epi64(x, 3); + } + else + { + return new long3(nextgreater(x.xy), + nextgreater(x.z)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long4 nextgreater(long4 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_incs_epi64(x, 4); + } + else + { + return new long4(nextgreater(x.xy), + nextgreater(x.zw)); + } + } + + + /// Returns the next closest greater than . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quarter nextgreater(quarter x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return asquarter(Xse.inc_pq(Sse2.cvtsi32_si128(x.value), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 1).Byte0); + } + else + { + int __x = assbyte(x); + int summand; + + if (optimizations.Promises(Promise.NonZero)) + { + if (optimizations.Promises(Promise.Positive) | optimizations.Promises(Promise.Negative)) + { + summand = 1; + } + else + { + summand = 1 | (__x >> 31); + } + } + else + { + int notNegative0 = -tobyte((uint)__x != 0xFFFF_FF80); + summand = 1 | ((__x >> 31) & notNegative0); + __x = (__x & notNegative0); + } + + if (!optimizations.Promises(Promise.Unsafe0)) + { + int notNanInf = -tobyte((__x & quarter.SIGNALING_EXPONENT) != quarter.SIGNALING_EXPONENT); + summand &= notNanInf; + } + + if (optimizations.Promises(Promise.Negative)) + { + return asquarter((byte)(__x - summand)); + } + else + { + return asquarter((byte)(__x + summand)); + } + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quarter2 nextgreater(quarter2 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.inc_pq(x, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 2); + } + else + { + return new quarter2(nextgreater(x.x, optimizations), + nextgreater(x.y, optimizations)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quarter3 nextgreater(quarter3 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.inc_pq(x, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 3); + } + else + { + return new quarter3(nextgreater(x.x, optimizations), + nextgreater(x.y, optimizations), + nextgreater(x.z, optimizations)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quarter4 nextgreater(quarter4 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.inc_pq(x, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 4); + } + else + { + return new quarter4(nextgreater(x.x, optimizations), + nextgreater(x.y, optimizations), + nextgreater(x.z, optimizations), + nextgreater(x.w, optimizations)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quarter8 nextgreater(quarter8 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.inc_pq(x, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 8); + } + else + { + return new quarter8(nextgreater(x.x0, optimizations), + nextgreater(x.x1, optimizations), + nextgreater(x.x2, optimizations), + nextgreater(x.x3, optimizations), + nextgreater(x.x4, optimizations), + nextgreater(x.x5, optimizations), + nextgreater(x.x6, optimizations), + nextgreater(x.x7, optimizations)); + } + } + + + /// Returns the next closest greater than . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either half.PositiveInfinity, half.NegativeInfinity or half.NaN. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static half nextgreater(half x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return ashalf(Xse.inc_ph(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 1).UShort0); + } + else + { + int __x = asshort(x); + int summand; + + if (optimizations.Promises(Promise.NonZero)) + { + if (optimizations.Promises(Promise.Positive) | optimizations.Promises(Promise.Negative)) + { + summand = 1; + } + else + { + summand = 1 | (__x >> 31); + } + } + else + { + int notNegative0 = -tobyte((uint)__x != 0xFFFF_8000); + summand = 1 | ((__x >> 31) & notNegative0); + __x = (__x & notNegative0); + } + + if (!optimizations.Promises(Promise.Unsafe0)) + { + int notNanInf = -tobyte((__x & F16_SIGNALING_EXPONENT) != F16_SIGNALING_EXPONENT); + summand &= notNanInf; + } + + if (optimizations.Promises(Promise.Negative)) + { + return ashalf((ushort)(__x - summand)); + } + else + { + return ashalf((ushort)(__x + summand)); + } + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either half.PositiveInfinity, half.NegativeInfinity or half.NaN. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static half2 nextgreater(half2 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToHalf2(Xse.inc_ph(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 2)); + } + else + { + return new half2(nextgreater(x.x, optimizations), + nextgreater(x.y, optimizations)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either half.PositiveInfinity, half.NegativeInfinity or half.NaN. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static half3 nextgreater(half3 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToHalf3(Xse.inc_ph(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 3)); + } + else + { + return new half3(nextgreater(x.x, optimizations), + nextgreater(x.y, optimizations), + nextgreater(x.z, optimizations)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either half.PositiveInfinity, half.NegativeInfinity or half.NaN. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static half4 nextgreater(half4 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToHalf4(Xse.inc_ph(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 4)); + } + else + { + return new half4(nextgreater(x.x, optimizations), + nextgreater(x.y, optimizations), + nextgreater(x.z, optimizations), + nextgreater(x.w, optimizations)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either half.PositiveInfinity, half.NegativeInfinity or half.NaN. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static half8 nextgreater(half8 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.inc_ph(x, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 8); + } + else + { + return new half8(nextgreater(x.x0, optimizations), + nextgreater(x.x1, optimizations), + nextgreater(x.x2, optimizations), + nextgreater(x.x3, optimizations), + nextgreater(x.x4, optimizations), + nextgreater(x.x5, optimizations), + nextgreater(x.x6, optimizations), + nextgreater(x.x7, optimizations)); + } + } + + + /// Returns the next closest greater than . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float nextgreater(float x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.inc_ps(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 1).Float0; + } + else + { + int __x = math.asint(x); + int summand; + + if (optimizations.Promises(Promise.NonZero)) + { + if (optimizations.Promises(Promise.Positive) | optimizations.Promises(Promise.Negative)) + { + summand = 1; + } + else + { + summand = 1 | (__x >> 31); + } + } + else + { + int notNegative0 = -tobyte(__x != 1 << 31); + summand = 1 | ((__x >> 31) & notNegative0); + __x = (__x & notNegative0); + } + + if (!optimizations.Promises(Promise.Unsafe0)) + { + int notNanInf = -tobyte((__x & F32_SIGNALING_EXPONENT) != F32_SIGNALING_EXPONENT); + summand &= notNanInf; + } + + if (optimizations.Promises(Promise.Negative)) + { + return math.asfloat(__x - summand); + } + else + { + return math.asfloat(__x + summand); + } + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float2 nextgreater(float2 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToFloat2(Xse.inc_ps(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 2)); + } + else + { + return new float2(nextgreater(x.x, optimizations), + nextgreater(x.y, optimizations)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 nextgreater(float3 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToFloat3(Xse.inc_ps(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 3)); + } + else + { + return new float3(nextgreater(x.x, optimizations), + nextgreater(x.y, optimizations), + nextgreater(x.z, optimizations)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float4 nextgreater(float4 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToFloat4(Xse.inc_ps(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 4)); + } + else + { + return new float4(nextgreater(x.x, optimizations), + nextgreater(x.y, optimizations), + nextgreater(x.z, optimizations), + nextgreater(x.w, optimizations)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float8 nextgreater(float8 x, Promise optimizations = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_inc_ps(x, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0)); + } + else + { + return new float8(nextgreater(x.v4_0, optimizations), + nextgreater(x.v4_4, optimizations)); + } + } + + + /// Returns the next closest greater than . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double nextgreater(double x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.inc_pd(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0)).Double0; + } + else + { + long __x = math.aslong(x); + long summand; + + if (optimizations.Promises(Promise.NonZero)) + { + if (optimizations.Promises(Promise.Positive) | optimizations.Promises(Promise.Negative)) + { + summand = 1; + } + else + { + summand = 1 | (__x >> 63); + } + } + else + { + long notNegative0 = -(long)tobyte(__x != 1L << 63); + summand = 1 | ((__x >> 63) & notNegative0); + __x = (__x & notNegative0); + } + + if (!optimizations.Promises(Promise.Unsafe0)) + { + long notNanInf = -(long)tobyte((__x & F64_SIGNALING_EXPONENT) != F64_SIGNALING_EXPONENT); + summand &= notNanInf; + } + + if (optimizations.Promises(Promise.Negative)) + { + return math.asdouble(__x - summand); + } + else + { + return math.asdouble(__x + summand); + } + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double2 nextgreater(double2 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToDouble2(Xse.inc_pd(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0))); + } + else + { + return new double2(nextgreater(x.x, optimizations), + nextgreater(x.y, optimizations)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double3 nextgreater(double3 x, Promise optimizations = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return RegisterConversion.ToDouble3(Xse.mm256_inc_pd(RegisterConversion.ToV256(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 3)); + } + else + { + return new double3(nextgreater(x.xy, optimizations), + nextgreater(x.z, optimizations)); + } + } + + /// Returns a , where each component is the next closest greater than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double4 nextgreater(double4 x, Promise optimizations = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return RegisterConversion.ToDouble4(Xse.mm256_inc_pd(RegisterConversion.ToV256(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 4)); + } + else + { + return new double4(nextgreater(x.xy, optimizations), + nextgreater(x.zw, optimizations)); + } + } + } +} diff --git a/Runtime/Math Lib/Functions/Arithmetic/Next Greater.cs.meta b/Runtime/Math Lib/Functions/Arithmetic/Next Greater.cs.meta new file mode 100644 index 0000000..81b427f --- /dev/null +++ b/Runtime/Math Lib/Functions/Arithmetic/Next Greater.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 379c3659eef937746a7295bed42bd163 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Math Lib/Functions/Arithmetic/Next Smaller.cs b/Runtime/Math Lib/Functions/Arithmetic/Next Smaller.cs new file mode 100644 index 0000000..f13d6cc --- /dev/null +++ b/Runtime/Math Lib/Functions/Arithmetic/Next Smaller.cs @@ -0,0 +1,1720 @@ +using System.Runtime.CompilerServices; +using Unity.Burst.Intrinsics; +using Unity.Mathematics; +using MaxMath.Intrinsics; + +using static Unity.Burst.Intrinsics.X86; +using static MaxMath.LUT.FLOATING_POINT; + +namespace MaxMath +{ + namespace Intrinsics + { + unsafe public static partial class Xse + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 dec_pq(v128 a, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + //promiseNonZero |= constexpr.ALL_NEQ_PQ(a, 0f, elements); + //promisePositive |= constexpr.ALL_GT_PQ(a, 0f, elements); + //promiseNegative |= constexpr.ALL_LT_PQ(a, 0f, elements); + //promiseNotNanInf |= constexpr.ALL_NOTNAN_PQ(a, elements) && constexpr.ALL_NEQ_PQ(a, quarter.PositiveInfinity, elements) && constexpr.ALL_NEQ_PH(a, quarter.NegativeInfinity, elements); + + v128 summand; + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = setall_si128(); + } + else + { + v128 ONE = Sse2.set1_epi8(1); + + if (Sse4_1.IsSse41Supported) + { + summand = Sse4_1.blendv_epi8(ONE, setall_si128(), a); + } + else + { + summand = Sse2.or_si128(srai_epi8(a, 7), ONE); + } + } + } + else + { + v128 ONE = Sse2.set1_epi8(1); + v128 NEGATIVE_ZERO = Sse2.set1_epi8(unchecked((sbyte)(1 << 7))); + v128 SUMMAND_IF_ZERO = Sse2.set1_epi8(unchecked((sbyte)0b1000_0010)); + + v128 isZero = Sse2.or_si128(Sse2.cmpeq_epi8(a, Sse2.setzero_si128()), Sse2.cmpeq_epi8(a, NEGATIVE_ZERO)); + summand = ternarylogic_si128(isZero, srai_epi8(a, 7), ONE, TernaryOperation.OxAE); + a = ternarylogic_si128(a, SUMMAND_IF_ZERO, isZero, TernaryOperation.OxF8); + } + + if (!promiseNotNanInf) + { + v128 SIGNALING_EXPONENT = Sse2.set1_epi8(quarter.SIGNALING_EXPONENT); + + v128 nanInf = Sse2.cmpeq_epi8(SIGNALING_EXPONENT, Sse2.and_si128(a, SIGNALING_EXPONENT)); + summand = Sse2.andnot_si128(nanInf, summand); + } + + if (promisePositive) + { + return Sse2.add_epi8(a, summand); + } + else + { + return Sse2.sub_epi8(a, summand); + } + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 dec_ph(v128 a, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + //promiseNonZero |= constexpr.ALL_NEQ_PH(a, 0f, elements); + //promisePositive |= constexpr.ALL_GT_PH(a, 0f, elements); + //promiseNegative |= constexpr.ALL_LT_PH(a, 0f, elements); + //promiseNotNanInf |= constexpr.ALL_NOTNAN_PH(a, elements) && constexpr.ALL_NEQ_PH(a, (half)float.PositiveInfinity, elements) && constexpr.ALL_NEQ_PH(a, (half)float.NegativeInfinity, elements); + + v128 summand; + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = setall_si128(); + } + else + { + v128 ONE = Sse2.set1_epi16(1); + + summand = Sse2.or_si128(Sse2.srai_epi16(a, 15), ONE); + } + } + else + { + v128 ONE = Sse2.set1_epi16(1); + v128 NEGATIVE_ZERO = Sse2.set1_epi16(unchecked((short)(1 << 15))); + v128 SUMMAND_IF_ZERO = Sse2.set1_epi16(unchecked((short)0x8002)); + + v128 isZero = Sse2.or_si128(Sse2.cmpeq_epi16(a, Sse2.setzero_si128()), Sse2.cmpeq_epi16(a, NEGATIVE_ZERO)); + summand = ternarylogic_si128(isZero, Sse2.srai_epi16(a, 15), ONE, TernaryOperation.OxAE); + a = ternarylogic_si128(a, SUMMAND_IF_ZERO, isZero, TernaryOperation.OxF8); + } + + if (!promiseNotNanInf) + { + v128 SIGNALING_EXPONENT = Sse2.set1_epi16((short)F16_SIGNALING_EXPONENT); + + v128 nanInf = Sse2.cmpeq_epi16(SIGNALING_EXPONENT, Sse2.and_si128(a, SIGNALING_EXPONENT)); + summand = Sse2.andnot_si128(nanInf, summand); + } + + if (promisePositive) + { + return Sse2.add_epi16(a, summand); + } + else + { + return Sse2.sub_epi16(a, summand); + } + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 dec_ps(v128 a, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false, byte elements = 4) + { + if (Sse2.IsSse2Supported) + { + promiseNonZero |= constexpr.ALL_NEQ_PS(a, 0f, elements); + promisePositive |= constexpr.ALL_GT_PS(a, 0f, elements); + promiseNegative |= constexpr.ALL_LT_PS(a, 0f, elements); + promiseNotNanInf |= constexpr.ALL_NOTNAN_PS(a, elements) && constexpr.ALL_NEQ_PS(a, float.PositiveInfinity, elements) && constexpr.ALL_NEQ_PS(a, float.NegativeInfinity, elements); + + v128 summand; + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = setall_si128(); + } + else + { + v128 ONE = Sse2.set1_epi32(1); + + if (Sse4_1.IsSse41Supported) + { + summand = Sse4_1.blendv_ps(ONE, setall_si128(), a); + } + else + { + summand = Sse2.or_si128(Sse2.srai_epi32(a, 31), ONE); + } + } + } + else + { + v128 ONE = Sse2.set1_epi32(1); + v128 NEGATIVE_ZERO = Sse2.set1_epi32(unchecked((int)(1 << 31))); + v128 SUMMAND_IF_ZERO = Sse2.set1_epi32(unchecked((int)0x8000_0002)); + + v128 isZero = Sse2.or_si128(Sse2.cmpeq_epi32(a, Sse2.setzero_si128()), Sse2.cmpeq_epi32(a, NEGATIVE_ZERO)); + summand = ternarylogic_si128(isZero, Sse2.srai_epi32(a, 31), ONE, TernaryOperation.OxAE); + a = ternarylogic_si128(a, SUMMAND_IF_ZERO, isZero, TernaryOperation.OxF8); + } + + if (!promiseNotNanInf) + { + v128 SIGNALING_EXPONENT = Sse2.set1_epi32(F32_SIGNALING_EXPONENT); + + v128 nanInf = Sse2.cmpeq_epi32(SIGNALING_EXPONENT, Sse2.and_si128(a, SIGNALING_EXPONENT)); + summand = Sse2.andnot_si128(nanInf, summand); + } + + if (promisePositive) + { + return Sse2.add_epi32(a, summand); + } + else + { + return Sse2.sub_epi32(a, summand); + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_dec_ps(v256 a, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false) + { + if (Avx2.IsAvx2Supported) + { + promiseNonZero |= constexpr.ALL_NEQ_PS(a, 0f); + promisePositive |= constexpr.ALL_GT_PS(a, 0f); + promiseNegative |= constexpr.ALL_LT_PS(a, 0f); + promiseNotNanInf |= constexpr.ALL_NOTNAN_PS(a) && constexpr.ALL_NEQ_PS(a, float.PositiveInfinity) && constexpr.ALL_NEQ_PS(a, float.NegativeInfinity); + + v256 summand; + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = mm256_setall_si256(); + } + else + { + v256 ONE = Avx.mm256_set1_epi32(1); + + summand = Avx.mm256_blendv_ps(ONE, mm256_setall_si256(), a); + } + } + else + { + v256 ONE = Avx.mm256_set1_epi32(1); + v256 NEGATIVE_ZERO = Avx.mm256_set1_epi32(unchecked((int)(1 << 31))); + v256 SUMMAND_IF_ZERO = Avx.mm256_set1_epi32(unchecked((int)0x8000_0002)); + + v256 isZero = Avx2.mm256_or_si256(Avx2.mm256_cmpeq_epi32(a, Avx.mm256_setzero_si256()), Avx2.mm256_cmpeq_epi32(a, NEGATIVE_ZERO)); + summand = mm256_ternarylogic_si256(isZero, Avx2.mm256_srai_epi32(a, 31), ONE, TernaryOperation.OxAE); + a = mm256_ternarylogic_si256(a, SUMMAND_IF_ZERO, isZero, TernaryOperation.OxF8); + } + + if (!promiseNotNanInf) + { + v256 SIGNALING_EXPONENT = Avx.mm256_set1_epi32(F32_SIGNALING_EXPONENT); + + v256 nanInf = Avx2.mm256_cmpeq_epi32(SIGNALING_EXPONENT, Avx2.mm256_and_si256(a, SIGNALING_EXPONENT)); + summand = Avx2.mm256_andnot_si256(nanInf, summand); + } + + if (promisePositive) + { + return Avx2.mm256_add_epi32(a, summand); + } + else + { + return Avx2.mm256_sub_epi32(a, summand); + } + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 dec_pd(v128 a, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false) + { + if (Sse2.IsSse2Supported) + { + promiseNonZero |= constexpr.ALL_NEQ_PD(a, 0d); + promisePositive |= constexpr.ALL_GT_PD(a, 0d); + promiseNegative |= constexpr.ALL_LT_PD(a, 0d); + promiseNotNanInf |= constexpr.ALL_NOTNAN_PD(a) && constexpr.ALL_NEQ_PD(a, double.PositiveInfinity) && constexpr.ALL_NEQ_PD(a, double.NegativeInfinity); + + v128 summand; + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = setall_si128(); + } + else + { + v128 ONE = Sse2.set1_epi64x(1); + + if (Sse4_1.IsSse41Supported) + { + summand = Sse4_1.blendv_pd(ONE, setall_si128(), a); + } + else + { + summand = Sse2.or_si128(srai_epi64(a, 63), ONE); + } + } + } + else + { + v128 ONE = Sse2.set1_epi64x(1); + v128 NEGATIVE_ZERO = Sse2.set1_epi64x(unchecked((long)(1ul << 64))); + v128 SUMMAND_IF_ZERO = Sse2.set1_epi64x(unchecked((long)0x8000_0000_0000_0002)); + + v128 isZero = Sse2.or_si128(cmpeq_epi64(a, Sse2.setzero_si128()), cmpeq_epi64(a, NEGATIVE_ZERO)); + summand = ternarylogic_si128(isZero, srai_epi64(a, 63), ONE, TernaryOperation.OxAE); + a = ternarylogic_si128(a, SUMMAND_IF_ZERO, isZero, TernaryOperation.OxF8); + } + + if (!promiseNotNanInf) + { + v128 SIGNALING_EXPONENT = Sse2.set1_epi64x(F64_SIGNALING_EXPONENT); + + v128 nanInf; + if (Sse4_1.IsSse41Supported) + { + nanInf = Sse4_1.cmpeq_epi64(SIGNALING_EXPONENT, Sse2.and_si128(a, SIGNALING_EXPONENT)); + } + else + { + nanInf = Sse2.shuffle_epi32(Sse2.cmpeq_epi32(SIGNALING_EXPONENT, Sse2.and_si128(a, SIGNALING_EXPONENT)), Sse.SHUFFLE(3, 3, 1, 1)); + } + + summand = Sse2.andnot_si128(nanInf, summand); + } + + if (promisePositive) + { + return Sse2.add_epi64(a, summand); + } + else + { + return Sse2.sub_epi64(a, summand); + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_dec_pd(v256 a, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false, byte elements = 4) + { + if (Avx2.IsAvx2Supported) + { + promiseNonZero |= constexpr.ALL_NEQ_PD(a, 0d, elements); + promisePositive |= constexpr.ALL_GT_PD(a, 0d, elements); + promiseNegative |= constexpr.ALL_LT_PD(a, 0d, elements); + promiseNotNanInf |= constexpr.ALL_NOTNAN_PD(a, elements) && constexpr.ALL_NEQ_PD(a, double.PositiveInfinity, elements) && constexpr.ALL_NEQ_PD(a, double.NegativeInfinity, elements); + + v256 summand; + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = mm256_setall_si256(); + } + else + { + v256 ONE = Avx.mm256_set1_epi64x(1); + + summand = Avx.mm256_blendv_pd(ONE, mm256_setall_si256(), a); + } + } + else + { + v256 ONE = Avx.mm256_set1_epi64x(1); + v256 NEGATIVE_ZERO = Avx.mm256_set1_epi64x(unchecked((long)(1ul << 64))); + v256 SUMMAND_IF_ZERO = Avx.mm256_set1_epi64x(unchecked((long)0x8000_0000_0000_0002)); + + v256 isZero = Avx2.mm256_or_si256(Avx2.mm256_cmpeq_epi64(a, Avx.mm256_setzero_si256()), Avx2.mm256_cmpeq_epi64(a, NEGATIVE_ZERO)); + summand = mm256_ternarylogic_si256(isZero, mm256_srai_epi64(a, 63), ONE, TernaryOperation.OxAE); + a = mm256_ternarylogic_si256(a, SUMMAND_IF_ZERO, isZero, TernaryOperation.OxF8); + } + + if (!promiseNotNanInf) + { + v256 SIGNALING_EXPONENT = Avx.mm256_set1_epi64x(F64_SIGNALING_EXPONENT); + + v256 nanInf = Avx2.mm256_cmpeq_epi64(SIGNALING_EXPONENT, Avx2.mm256_and_si256(a, SIGNALING_EXPONENT)); + summand = Avx2.mm256_andnot_si256(nanInf, summand); + } + + if (promisePositive) + { + return Avx2.mm256_add_epi64(a, summand); + } + else + { + return Avx2.mm256_sub_epi64(a, summand); + } + } + else throw new IllegalInstructionException(); + } + } + } + + + unsafe public static partial class maxmath + { + /// Returns the next closest smaller than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt128 nextsmaller(UInt128 x) + { + return x - tobyte(x != UInt128.MinValue); + } + + + /// Returns the next closest smaller than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Int128 nextsmaller(Int128 x) + { + return x - tobyte(x != Int128.MinValue); + } + + + /// Returns the next closest smaller than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte nextsmaller(byte x) + { + return (byte)(x - tobyte(x != byte.MinValue)); + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte2 nextsmaller(byte2 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epu8(x); + } + else + { + return new byte2(nextsmaller(x.x), + nextsmaller(x.y)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte3 nextsmaller(byte3 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epu8(x); + } + else + { + return new byte3(nextsmaller(x.x), + nextsmaller(x.y), + nextsmaller(x.z)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte4 nextsmaller(byte4 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epu8(x); + } + else + { + return new byte4(nextsmaller(x.x), + nextsmaller(x.y), + nextsmaller(x.z), + nextsmaller(x.w)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte8 nextsmaller(byte8 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epu8(x); + } + else + { + return new byte8(nextsmaller(x.x0), + nextsmaller(x.x1), + nextsmaller(x.x2), + nextsmaller(x.x3), + nextsmaller(x.x4), + nextsmaller(x.x5), + nextsmaller(x.x6), + nextsmaller(x.x7)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte16 nextsmaller(byte16 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epu8(x); + } + else + { + return new byte16(nextsmaller(x.x0), + nextsmaller(x.x1), + nextsmaller(x.x2), + nextsmaller(x.x3), + nextsmaller(x.x4), + nextsmaller(x.x5), + nextsmaller(x.x6), + nextsmaller(x.x7), + nextsmaller(x.x8), + nextsmaller(x.x9), + nextsmaller(x.x10), + nextsmaller(x.x11), + nextsmaller(x.x12), + nextsmaller(x.x13), + nextsmaller(x.x14), + nextsmaller(x.x15)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte32 nextsmaller(byte32 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_decs_epu8(x); + } + else + { + return new byte32(nextsmaller(x.v16_0), + nextsmaller(x.v16_16)); + } + } + + + /// Returns the next closest smaller than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte nextsmaller(sbyte x) + { + return (sbyte)(x - tobyte(x != sbyte.MinValue)); + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte2 nextsmaller(sbyte2 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epi8(x); + } + else + { + return new sbyte2(nextsmaller(x.x), + nextsmaller(x.y)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte3 nextsmaller(sbyte3 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epi8(x); + } + else + { + return new sbyte3(nextsmaller(x.x), + nextsmaller(x.y), + nextsmaller(x.z)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte4 nextsmaller(sbyte4 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epi8(x); + } + else + { + return new sbyte4(nextsmaller(x.x), + nextsmaller(x.y), + nextsmaller(x.z), + nextsmaller(x.w)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte8 nextsmaller(sbyte8 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epi8(x); + } + else + { + return new sbyte8(nextsmaller(x.x0), + nextsmaller(x.x1), + nextsmaller(x.x2), + nextsmaller(x.x3), + nextsmaller(x.x4), + nextsmaller(x.x5), + nextsmaller(x.x6), + nextsmaller(x.x7)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte16 nextsmaller(sbyte16 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epi8(x); + } + else + { + return new sbyte16(nextsmaller(x.x0), + nextsmaller(x.x1), + nextsmaller(x.x2), + nextsmaller(x.x3), + nextsmaller(x.x4), + nextsmaller(x.x5), + nextsmaller(x.x6), + nextsmaller(x.x7), + nextsmaller(x.x8), + nextsmaller(x.x9), + nextsmaller(x.x10), + nextsmaller(x.x11), + nextsmaller(x.x12), + nextsmaller(x.x13), + nextsmaller(x.x14), + nextsmaller(x.x15)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte32 nextsmaller(sbyte32 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_decs_epi8(x); + } + else + { + return new sbyte32(nextsmaller(x.v16_0), + nextsmaller(x.v16_16)); + } + } + + + /// Returns the next closest smaller than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort nextsmaller(ushort x) + { + return (ushort)(x - tobyte(x != ushort.MinValue)); + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort2 nextsmaller(ushort2 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epu16(x); + } + else + { + return new ushort2(nextsmaller(x.x), + nextsmaller(x.y)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort3 nextsmaller(ushort3 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epu16(x); + } + else + { + return new ushort3(nextsmaller(x.x), + nextsmaller(x.y), + nextsmaller(x.z)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort4 nextsmaller(ushort4 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epu16(x); + } + else + { + return new ushort4(nextsmaller(x.x), + nextsmaller(x.y), + nextsmaller(x.z), + nextsmaller(x.w)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort8 nextsmaller(ushort8 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epu16(x); + } + else + { + return new ushort8(nextsmaller(x.x0), + nextsmaller(x.x1), + nextsmaller(x.x2), + nextsmaller(x.x3), + nextsmaller(x.x4), + nextsmaller(x.x5), + nextsmaller(x.x6), + nextsmaller(x.x7)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort16 nextsmaller(ushort16 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_decs_epu16(x); + } + else + { + return new ushort16(nextsmaller(x.v8_0), + nextsmaller(x.v8_8)); + } + } + + + /// Returns the next closest smaller than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short nextsmaller(short x) + { + return (short)(x - tobyte(x != short.MinValue)); + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short2 nextsmaller(short2 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epi16(x); + } + else + { + return new short2(nextsmaller(x.x), + nextsmaller(x.y)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short3 nextsmaller(short3 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epi16(x); + } + else + { + return new short3(nextsmaller(x.x), + nextsmaller(x.y), + nextsmaller(x.z)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short4 nextsmaller(short4 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epi16(x); + } + else + { + return new short4(nextsmaller(x.x), + nextsmaller(x.y), + nextsmaller(x.z), + nextsmaller(x.w)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short8 nextsmaller(short8 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epi16(x); + } + else + { + return new short8(nextsmaller(x.x0), + nextsmaller(x.x1), + nextsmaller(x.x2), + nextsmaller(x.x3), + nextsmaller(x.x4), + nextsmaller(x.x5), + nextsmaller(x.x6), + nextsmaller(x.x7)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short16 nextsmaller(short16 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_decs_epi16(x); + } + else + { + return new short16(nextsmaller(x.v8_0), + nextsmaller(x.v8_8)); + } + } + + + /// Returns the next closest smaller than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint nextsmaller(uint x) + { + return x - tobyte(x != uint.MinValue); + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint2 nextsmaller(uint2 x) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt2(Xse.decs_epu32(RegisterConversion.ToV128(x), 2)); + } + else + { + return new uint2(nextsmaller(x.x), + nextsmaller(x.y)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint3 nextsmaller(uint3 x) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt3(Xse.decs_epu32(RegisterConversion.ToV128(x), 3)); + } + else + { + return new uint3(nextsmaller(x.x), + nextsmaller(x.y), + nextsmaller(x.z)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint4 nextsmaller(uint4 x) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt4(Xse.decs_epu32(RegisterConversion.ToV128(x), 4)); + } + else + { + return new uint4(nextsmaller(x.x), + nextsmaller(x.y), + nextsmaller(x.z), + nextsmaller(x.w)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint8 nextsmaller(uint8 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_decs_epu32(x); + } + else + { + return new uint8(nextsmaller(x.v4_0), + nextsmaller(x.v4_4)); + } + } + + + /// Returns the next closest smaller than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int nextsmaller(int x) + { + return x - tobyte(x != int.MinValue); + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int2 nextsmaller(int2 x) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToInt2(Xse.decs_epi32(RegisterConversion.ToV128(x), 2)); + } + else + { + return new int2(nextsmaller(x.x), + nextsmaller(x.y)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int3 nextsmaller(int3 x) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToInt3(Xse.decs_epi32(RegisterConversion.ToV128(x), 3)); + } + else + { + return new int3(nextsmaller(x.x), + nextsmaller(x.y), + nextsmaller(x.z)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int4 nextsmaller(int4 x) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToInt4(Xse.decs_epi32(RegisterConversion.ToV128(x), 4)); + } + else + { + return new int4(nextsmaller(x.x), + nextsmaller(x.y), + nextsmaller(x.z), + nextsmaller(x.w)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int8 nextsmaller(int8 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_decs_epi32(x); + } + else + { + return new int8(nextsmaller(x.v4_0), + nextsmaller(x.v4_4)); + } + } + + + /// Returns the next closest smaller than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong nextsmaller(ulong x) + { + return x - tobyte(x != ulong.MinValue); + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong2 nextsmaller(ulong2 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epu64(x); + } + else + { + return new ulong2(nextsmaller(x.x), + nextsmaller(x.y)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong3 nextsmaller(ulong3 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_decs_epu64(x, 3); + } + else + { + return new ulong3(nextsmaller(x.xy), + nextsmaller(x.z)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong4 nextsmaller(ulong4 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_decs_epu64(x, 4); + } + else + { + return new ulong4(nextsmaller(x.xy), + nextsmaller(x.zw)); + } + } + + + /// Returns the next closest smaller than . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long nextsmaller(long x) + { + return x - tobyte(x != long.MinValue); + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long2 nextsmaller(long2 x) + { + if (Sse2.IsSse2Supported) + { + return Xse.decs_epi64(x); + } + else + { + return new long2(nextsmaller(x.x), + nextsmaller(x.y)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long3 nextsmaller(long3 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_decs_epi64(x, 3); + } + else + { + return new long3(nextsmaller(x.xy), + nextsmaller(x.z)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long4 nextsmaller(long4 x) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_decs_epi64(x, 4); + } + else + { + return new long4(nextsmaller(x.xy), + nextsmaller(x.zw)); + } + } + + + /// Returns the next closest smaller than . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quarter nextsmaller(quarter x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return asquarter(Xse.dec_pq(Sse2.cvtsi32_si128(x.value), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 1).Byte0); + } + else + { + int __x = assbyte(x); + int summand; + + if (optimizations.Promises(Promise.NonZero)) + { + if (optimizations.Promises(Promise.Positive) | optimizations.Promises(Promise.Negative)) + { + summand = 1; + } + else + { + summand = 1 | (__x >> 31); + } + } + else + { + int isNotZero = -tobyte((__x != unchecked((int)0xFFFF_FF80)) & (__x != 0)); + summand = 1 | ((__x >> 31) & isNotZero); + __x |= (int)andnot(0b1000_0010, (uint)isNotZero); + } + + if (!optimizations.Promises(Promise.Unsafe0)) + { + int notNanInf = -tobyte((__x & quarter.SIGNALING_EXPONENT) != quarter.SIGNALING_EXPONENT); + summand &= notNanInf; + } + + if (optimizations.Promises(Promise.Negative)) + { + return asquarter((byte)(__x + summand)); + } + else + { + return asquarter((byte)(__x - summand)); + } + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quarter2 nextsmaller(quarter2 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.dec_pq(x, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 2); + } + else + { + return new quarter2(nextsmaller(x.x, optimizations), + nextsmaller(x.y, optimizations)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quarter3 nextsmaller(quarter3 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.dec_pq(x, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 3); + } + else + { + return new quarter3(nextsmaller(x.x, optimizations), + nextsmaller(x.y, optimizations), + nextsmaller(x.z, optimizations)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quarter4 nextsmaller(quarter4 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.dec_pq(x, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 4); + } + else + { + return new quarter4(nextsmaller(x.x, optimizations), + nextsmaller(x.y, optimizations), + nextsmaller(x.z, optimizations), + nextsmaller(x.w, optimizations)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quarter8 nextsmaller(quarter8 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.dec_pq(x, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 8); + } + else + { + return new quarter8(nextsmaller(x.x0, optimizations), + nextsmaller(x.x1, optimizations), + nextsmaller(x.x2, optimizations), + nextsmaller(x.x3, optimizations), + nextsmaller(x.x4, optimizations), + nextsmaller(x.x5, optimizations), + nextsmaller(x.x6, optimizations), + nextsmaller(x.x7, optimizations)); + } + } + + + /// Returns the next closest smaller than . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either half.PositiveInfinity, half.NegativeInfinity or half.NaN. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static half nextsmaller(half x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return ashalf(Xse.dec_ph(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 1).UShort0); + } + else + { + int __x = asshort(x); + int summand; + + if (optimizations.Promises(Promise.NonZero)) + { + if (optimizations.Promises(Promise.Positive) | optimizations.Promises(Promise.Negative)) + { + summand = 1; + } + else + { + summand = 1 | (__x >> 31); + } + } + else + { + int isNotZero = -tobyte((__x != unchecked((int)0xFFFF_8000)) & (__x != 0)); + summand = 1 | ((__x >> 31) & isNotZero); + __x |= (int)andnot(0x8002u, (uint)isNotZero); + } + + if (!optimizations.Promises(Promise.Unsafe0)) + { + int notNanInf = -tobyte((__x & F16_SIGNALING_EXPONENT) != F16_SIGNALING_EXPONENT); + summand &= notNanInf; + } + + if (optimizations.Promises(Promise.Negative)) + { + return ashalf((ushort)(__x + summand)); + } + else + { + return ashalf((ushort)(__x - summand)); + } + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either half.PositiveInfinity, half.NegativeInfinity or half.NaN. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static half2 nextsmaller(half2 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToHalf2(Xse.dec_ph(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 2)); + } + else + { + return new half2(nextsmaller(x.x, optimizations), + nextsmaller(x.y, optimizations)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either half.PositiveInfinity, half.NegativeInfinity or half.NaN. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static half3 nextsmaller(half3 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToHalf3(Xse.dec_ph(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 3)); + } + else + { + return new half3(nextsmaller(x.x, optimizations), + nextsmaller(x.y, optimizations), + nextsmaller(x.z, optimizations)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either half.PositiveInfinity, half.NegativeInfinity or half.NaN. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static half4 nextsmaller(half4 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToHalf4(Xse.dec_ph(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 4)); + } + else + { + return new half4(nextsmaller(x.x, optimizations), + nextsmaller(x.y, optimizations), + nextsmaller(x.z, optimizations), + nextsmaller(x.w, optimizations)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either half.PositiveInfinity, half.NegativeInfinity or half.NaN. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static half8 nextsmaller(half8 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.dec_ph(x, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 8); + } + else + { + return new half8(nextsmaller(x.x0, optimizations), + nextsmaller(x.x1, optimizations), + nextsmaller(x.x2, optimizations), + nextsmaller(x.x3, optimizations), + nextsmaller(x.x4, optimizations), + nextsmaller(x.x5, optimizations), + nextsmaller(x.x6, optimizations), + nextsmaller(x.x7, optimizations)); + } + } + + + /// Returns the next closest smaller than . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float nextsmaller(float x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.dec_ps(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 1).Float0; + } + else + { + int __x = math.asint(x); + int summand; + + if (optimizations.Promises(Promise.NonZero)) + { + if (optimizations.Promises(Promise.Positive) | optimizations.Promises(Promise.Negative)) + { + summand = 1; + } + else + { + summand = 1 | (__x >> 31); + } + } + else + { + int isNotZero = -tobyte((__x != 1 << 31) & (__x != 0)); + summand = 1 | ((__x >> 31) & isNotZero); + __x |= (int)andnot(0x8000_0002u, (uint)isNotZero); + } + + if (!optimizations.Promises(Promise.Unsafe0)) + { + int notNanInf = -tobyte((__x & F32_SIGNALING_EXPONENT) != F32_SIGNALING_EXPONENT); + summand &= notNanInf; + } + + if (optimizations.Promises(Promise.Negative)) + { + return math.asfloat(__x + summand); + } + else + { + return math.asfloat(__x - summand); + } + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float2 nextsmaller(float2 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToFloat2(Xse.dec_ps(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 2)); + } + else + { + return new float2(nextsmaller(x.x, optimizations), + nextsmaller(x.y, optimizations)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 nextsmaller(float3 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToFloat3(Xse.dec_ps(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 3)); + } + else + { + return new float3(nextsmaller(x.x, optimizations), + nextsmaller(x.y, optimizations), + nextsmaller(x.z, optimizations)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float4 nextsmaller(float4 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToFloat4(Xse.dec_ps(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 4)); + } + else + { + return new float4(nextsmaller(x.x, optimizations), + nextsmaller(x.y, optimizations), + nextsmaller(x.z, optimizations), + nextsmaller(x.w, optimizations)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float8 nextsmaller(float8 x, Promise optimizations = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_dec_ps(x, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0)); + } + else + { + return new float8(nextsmaller(x.v4_0, optimizations), + nextsmaller(x.v4_4, optimizations)); + } + } + + + /// Returns the next closest smaller than . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double nextsmaller(double x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.dec_pd(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0)).Double0; + } + else + { + long __x = math.aslong(x); + long summand; + + if (optimizations.Promises(Promise.NonZero)) + { + if (optimizations.Promises(Promise.Positive) | optimizations.Promises(Promise.Negative)) + { + summand = 1; + } + else + { + summand = 1 | (__x >> 63); + } + } + else + { + long isNotZero = -tobyte((__x != 1L << 63) & (__x != 0)); + summand = 1 | ((__x >> 63) & isNotZero); + __x |= (long)andnot(0x8000_0000_0000_0002, (ulong)isNotZero); + } + + if (!optimizations.Promises(Promise.Unsafe0)) + { + long notNanInf = -(long)tobyte((__x & F64_SIGNALING_EXPONENT) != F64_SIGNALING_EXPONENT); + summand &= notNanInf; + } + + if (optimizations.Promises(Promise.Negative)) + { + return math.asdouble(__x + summand); + } + else + { + return math.asdouble(__x - summand); + } + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double2 nextsmaller(double2 x, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToDouble2(Xse.dec_pd(RegisterConversion.ToV128(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0))); + } + else + { + return new double2(nextsmaller(x.x, optimizations), + nextsmaller(x.y, optimizations)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double3 nextsmaller(double3 x, Promise optimizations = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return RegisterConversion.ToDouble3(Xse.mm256_dec_pd(RegisterConversion.ToV256(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 3)); + } + else + { + return new double3(nextsmaller(x.xy, optimizations), + nextsmaller(x.z, optimizations)); + } + } + + /// Returns a , where each component is the next closest smaller than the corresponding component in . + /// + /// A "" with its flag set returns incorrect results for any that is negative 0. + /// A "" with its flag set returns incorrect results for any that is negative or 0. + /// A "" with its flag set returns incorrect results for any that is positive or 0. + /// A "" with its flag set returns incorrect results for any that is either , or . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double4 nextsmaller(double4 x, Promise optimizations = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return RegisterConversion.ToDouble4(Xse.mm256_dec_pd(RegisterConversion.ToV256(x), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 4)); + } + else + { + return new double4(nextsmaller(x.xy, optimizations), + nextsmaller(x.zw, optimizations)); + } + } + } +} diff --git a/Runtime/Math Lib/Functions/Arithmetic/Next Smaller.cs.meta b/Runtime/Math Lib/Functions/Arithmetic/Next Smaller.cs.meta new file mode 100644 index 0000000..d635d02 --- /dev/null +++ b/Runtime/Math Lib/Functions/Arithmetic/Next Smaller.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9155ad909a8150f47a4c844196b18aed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Math Lib/Functions/Arithmetic/Next Toward.cs b/Runtime/Math Lib/Functions/Arithmetic/Next Toward.cs new file mode 100644 index 0000000..05d8c64 --- /dev/null +++ b/Runtime/Math Lib/Functions/Arithmetic/Next Toward.cs @@ -0,0 +1,2244 @@ +using System.Runtime.CompilerServices; +using Unity.Burst.Intrinsics; +using Unity.Mathematics; +using MaxMath.Intrinsics; + +using static Unity.Burst.Intrinsics.X86; +using static MaxMath.LUT.FLOATING_POINT; + +namespace MaxMath +{ + namespace Intrinsics + { + unsafe public static partial class Xse + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 toward_epu8(v128 a, v128 b, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_EQ_EPU8(b, byte.MinValue, elements)) + { + return decs_epu8(a); + } + if (constexpr.ALL_EQ_EPU8(b, byte.MaxValue, elements)) + { + return incs_epu8(a); + } + + return Sse2.sub_epi8(a, cmp_epu8(a, b, elements)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_toward_epu8(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + if (constexpr.ALL_EQ_EPU8(b, byte.MinValue)) + { + return mm256_decs_epu8(a); + } + if (constexpr.ALL_EQ_EPU8(b, byte.MaxValue)) + { + return mm256_incs_epu8(a); + } + + return Avx2.mm256_sub_epi8(a, mm256_cmp_epu8(a, b)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 toward_epu16(v128 a, v128 b, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_EQ_EPU16(b, ushort.MinValue, elements)) + { + return decs_epu16(a); + } + if (constexpr.ALL_EQ_EPU16(b, ushort.MaxValue, elements)) + { + return incs_epu16(a); + } + + return Sse2.sub_epi16(a, cmp_epu16(a, b, elements)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_toward_epu16(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + if (constexpr.ALL_EQ_EPU16(b, ushort.MinValue)) + { + return mm256_decs_epu16(a); + } + if (constexpr.ALL_EQ_EPU16(b, ushort.MaxValue)) + { + return mm256_incs_epu16(a); + } + + return Avx2.mm256_sub_epi16(a, mm256_cmp_epu16(a, b)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 toward_epu32(v128 a, v128 b, byte elements = 4) + { + if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_EQ_EPU32(b, uint.MinValue, elements)) + { + return decs_epu32(a, elements); + } + if (constexpr.ALL_EQ_EPU32(b, uint.MaxValue, elements)) + { + return incs_epu32(a, elements); + } + + return Sse2.sub_epi32(a, cmp_epu32(a, b, elements)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_toward_epu32(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + if (constexpr.ALL_EQ_EPU32(b, uint.MinValue)) + { + return mm256_decs_epu32(a); + } + if (constexpr.ALL_EQ_EPU32(b, uint.MaxValue)) + { + return mm256_incs_epu32(a); + } + + return Avx2.mm256_sub_epi32(a, mm256_cmp_epu32(a, b)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 toward_epu64(v128 a, v128 b) + { + if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_EQ_EPU64(b, ulong.MinValue)) + { + return decs_epu64(a); + } + if (constexpr.ALL_EQ_EPU64(b, ulong.MaxValue)) + { + return incs_epu64(a); + } + + return Sse2.sub_epi64(a, cmp_epu64(a, b)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_toward_epu64(v256 a, v256 b, byte elements = 4) + { + if (Avx2.IsAvx2Supported) + { + if (constexpr.ALL_EQ_EPU64(b, ulong.MinValue, elements)) + { + return mm256_decs_epu64(a, elements); + } + if (constexpr.ALL_EQ_EPU64(b, ulong.MaxValue, elements)) + { + return mm256_incs_epu64(a, elements); + } + + return Avx2.mm256_sub_epi64(a, mm256_cmp_epu64(a, b, elements)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 toward_epi8(v128 a, v128 b, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_EQ_EPI8(b, sbyte.MinValue, elements)) + { + return decs_epi8(a); + } + if (constexpr.ALL_EQ_EPI8(b, sbyte.MaxValue, elements)) + { + return incs_epi8(a); + } + + return Sse2.sub_epi8(a, cmp_epi8(a, b)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_toward_epi8(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + if (constexpr.ALL_EQ_EPI8(b, sbyte.MinValue)) + { + return mm256_decs_epi8(a); + } + if (constexpr.ALL_EQ_EPI8(b, sbyte.MaxValue)) + { + return mm256_incs_epi8(a); + } + + return Avx2.mm256_sub_epi8(a, mm256_cmp_epi8(a, b)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 toward_epi16(v128 a, v128 b, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_EQ_EPI16(b, short.MinValue, elements)) + { + return decs_epi16(a); + } + if (constexpr.ALL_EQ_EPI16(b, short.MaxValue, elements)) + { + return incs_epi16(a); + } + + return Sse2.sub_epi16(a, cmp_epi16(a, b)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_toward_epi16(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + if (constexpr.ALL_EQ_EPI16(b, short.MinValue)) + { + return mm256_decs_epi16(a); + } + if (constexpr.ALL_EQ_EPI16(b, short.MaxValue)) + { + return mm256_incs_epi16(a); + } + + return Avx2.mm256_sub_epi16(a, mm256_cmp_epi16(a, b)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 toward_epi32(v128 a, v128 b, byte elements = 4) + { + if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_EQ_EPI32(b, int.MinValue, elements)) + { + return decs_epi32(a, elements); + } + if (constexpr.ALL_EQ_EPI32(b, int.MaxValue, elements)) + { + return incs_epi32(a, elements); + } + + return Sse2.sub_epi32(a, cmp_epi32(a, b)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_toward_epi32(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + if (constexpr.ALL_EQ_EPI32(b, int.MinValue)) + { + return mm256_decs_epi32(a); + } + if (constexpr.ALL_EQ_EPI32(b, int.MaxValue)) + { + return mm256_incs_epi32(a); + } + + return Avx2.mm256_sub_epi32(a, mm256_cmp_epi32(a, b)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 toward_epi64(v128 a, v128 b) + { + if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_EQ_EPI64(b, long.MinValue)) + { + return decs_epi64(a); + } + if (constexpr.ALL_EQ_EPI64(b, long.MaxValue)) + { + return incs_epi64(a); + } + + return Sse2.sub_epi64(a, cmp_epi64(a, b)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_toward_epi64(v256 a, v256 b, byte elements = 4) + { + if (Avx2.IsAvx2Supported) + { + if (constexpr.ALL_EQ_EPI64(b, long.MinValue, elements)) + { + return mm256_decs_epi64(a, elements); + } + if (constexpr.ALL_EQ_EPI64(b, long.MaxValue, elements)) + { + return mm256_incs_epi64(a, elements); + } + + return Avx2.mm256_sub_epi64(a, mm256_cmp_epi64(a, b, elements)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 toward_pq(v128 a, v128 b, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + //promiseNonZero |= constexpr.ALL_NEQ_PQ(a, 0f, elements); + //promisePositive |= constexpr.ALL_GT_PQ(a, 0f, elements); + //promiseNegative |= constexpr.ALL_LT_PQ(a, 0f, elements); + //promiseNotNanInf |= constexpr.ALL_NOTNAN_PQ(a, elements) && constexpr.ALL_NOTNAN_PQ(b, elements) && constexpr.ALL_NEQ_PQ(a, float.PositiveInfinity, elements) && constexpr.ALL_NEQ_PQ(a, float.NegativeInfinity, elements); + + v128 ONE = Sse2.set1_epi8(1); + + v128 isGreater = quarter.Vectorized.cmpgt_pq(a, b, promiseNeitherNaN: promiseNotNanInf, promiseNeitherZero: promiseNonZero && constexpr.ALL_NEQ_EPU8(b, 0, elements) && constexpr.ALL_NEQ_EPU8(b, 0b1000_0000, elements), elements: elements); + v128 areDifferent = quarter.Vectorized.cmpneq_pq(a, b, promiseNeitherNaN: promiseNotNanInf, promiseNeitherZero: promiseNonZero && constexpr.ALL_NEQ_EPU8(b, 0, elements) && constexpr.ALL_NEQ_EPU8(b, 0b1000_0000, elements), elements: elements); + v128 summand; + + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = setall_si128(); + } + else + { + if (Sse4_1.IsSse41Supported) + { + summand = Sse4_1.blendv_epi8(ONE, setall_si128(), a); + } + else + { + summand = Sse2.or_si128(srai_epi8(a, 7), ONE); + } + } + + if (!promiseNotNanInf) + { + v128 SIGNALING_EXPONENT = Sse2.set1_epi8(quarter.SIGNALING_EXPONENT); + + v128 xInfinite = Sse2.cmpeq_epi8(SIGNALING_EXPONENT, Sse2.and_si128(SIGNALING_EXPONENT, a)); + v128 eitherNaN = quarter.Vectorized.cmpunord_pq(a, b, elements); + + summand = ternarylogic_si128(eitherNaN, xInfinite, summand, TernaryOperation.OxO2); + a = Sse2.or_si128(a, eitherNaN); + } + } + else + { + v128 NEGATIVE_ZERO = Sse2.set1_epi8(unchecked((sbyte)(1u << 7))); + v128 IF_ZERO = Sse2.set1_epi8(unchecked((sbyte)0x82u)); + + v128 isNegativeZero = Sse2.cmpeq_epi8(NEGATIVE_ZERO, a); + v128 isPositiveZero = Sse2.cmpeq_epi8(Sse2.setzero_si128(), a); + v128 zeroMask = ternarylogic_si128(isNegativeZero, isPositiveZero, isGreater, TernaryOperation.Ox87); + + summand = ternarylogic_si128(ONE, srai_epi8(a, 7), zeroMask, TernaryOperation.OxF8); + v128 aPart0 = ternarylogic_si128(a, isGreater, zeroMask, TernaryOperation.OxEO); + v128 aPart1 = ternarylogic_si128(zeroMask, IF_ZERO, isGreater, TernaryOperation.OxO8); + + if (promiseNotNanInf) + { + a = Sse2.or_si128(aPart0, aPart1); + } + else + { + v128 SIGNALING_EXPONENT = Sse2.set1_epi8(quarter.SIGNALING_EXPONENT); + + v128 xInfinite = Sse2.cmpeq_epi8(SIGNALING_EXPONENT, Sse2.and_si128(SIGNALING_EXPONENT, a)); + v128 eitherNaN = quarter.Vectorized.cmpunord_pq(a, b, elements); + + summand = ternarylogic_si128(eitherNaN, xInfinite, summand, TernaryOperation.OxO2); + a = ternarylogic_si128(eitherNaN, aPart0, aPart1, TernaryOperation.OxFE); + } + } + + summand = ternarylogic_si128(isGreater, summand, areDifferent, TernaryOperation.Ox78); + summand = Sse2.sub_epi8(summand, isGreater); + + if (promisePositive) + { + return Sse2.sub_epi8(a, summand); + } + else + { + return Sse2.add_epi8(a, summand); + } + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 toward_ph(v128 a, v128 b, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false, byte elements = 4) + { + if (Sse2.IsSse2Supported) + { + //promiseNonZero |= constexpr.ALL_NEQ_PH(a, 0f, elements); + //promisePositive |= constexpr.ALL_GT_PH(a, 0f, elements); + //promiseNegative |= constexpr.ALL_LT_PH(a, 0f, elements); + //promiseNotNanInf |= constexpr.ALL_NOTNAN_PH(a, elements) && constexpr.ALL_NOTNAN_PH(b, elements) && constexpr.ALL_NEQ_PH(a, float.PositiveInfinity, elements) && constexpr.ALL_NEQ_PH(a, float.NegativeInfinity, elements); + + v128 ONE = Sse2.set1_epi16(1); + + v128 isGreater = cmpgt_ph(a, b, promiseNeitherNaN: promiseNotNanInf, promiseNeitherZero: promiseNonZero && constexpr.ALL_NEQ_EPU16(b, 0, elements) && constexpr.ALL_NEQ_EPU16(b, 0x8000, elements), elements: elements); + v128 areDifferent = cmpneq_ph(a, b, promiseNeitherNaN: promiseNotNanInf, promiseNeitherZero: promiseNonZero && constexpr.ALL_NEQ_EPU16(b, 0, elements) && constexpr.ALL_NEQ_EPU16(b, 0x8000, elements), elements: elements); + v128 summand; + + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = setall_si128(); + } + else + { + summand = Sse2.or_si128(Sse2.srai_epi16(a, 15), ONE); + } + + if (!promiseNotNanInf) + { + v128 SIGNALING_EXPONENT = Sse2.set1_epi16(F16_SIGNALING_EXPONENT); + + v128 xInfinite = Sse2.cmpeq_epi16(SIGNALING_EXPONENT, Sse2.and_si128(SIGNALING_EXPONENT, a)); + v128 eitherNaN = cmpunord_ph(a, b, elements); + + summand = ternarylogic_si128(eitherNaN, xInfinite, summand, TernaryOperation.OxO2); + a = Sse2.or_si128(a, eitherNaN); + } + } + else + { + v128 NEGATIVE_ZERO = Sse2.set1_epi16(unchecked((short)(1u << 15))); + v128 IF_ZERO = Sse2.set1_epi16(unchecked((short)0x8002u)); + + v128 isNegativeZero = Sse2.cmpeq_epi16(NEGATIVE_ZERO, a); + v128 isPositiveZero = Sse2.cmpeq_epi16(Sse2.setzero_si128(), a); + v128 zeroMask = ternarylogic_si128(isNegativeZero, isPositiveZero, isGreater, TernaryOperation.Ox87); + + summand = ternarylogic_si128(ONE, Sse2.srai_epi16(a, 15), zeroMask, TernaryOperation.OxF8); + v128 aPart0 = ternarylogic_si128(a, isGreater, zeroMask, TernaryOperation.OxEO); + v128 aPart1 = ternarylogic_si128(zeroMask, IF_ZERO, isGreater, TernaryOperation.OxO8); + + if (promiseNotNanInf) + { + a = Sse2.or_si128(aPart0, aPart1); + } + else + { + v128 SIGNALING_EXPONENT = Sse2.set1_epi16(F16_SIGNALING_EXPONENT); + + v128 xInfinite = Sse2.cmpeq_epi16(SIGNALING_EXPONENT, Sse2.and_si128(SIGNALING_EXPONENT, a)); + v128 eitherNaN = cmpunord_ph(a, b, elements); + + summand = ternarylogic_si128(eitherNaN, xInfinite, summand, TernaryOperation.OxO2); + a = ternarylogic_si128(eitherNaN, aPart0, aPart1, TernaryOperation.OxFE); + } + } + + summand = ternarylogic_si128(isGreater, summand, areDifferent, TernaryOperation.Ox78); + summand = Sse2.sub_epi16(summand, isGreater); + + if (promisePositive) + { + return Sse2.sub_epi16(a, summand); + } + else + { + return Sse2.add_epi16(a, summand); + } + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 toward_ps(v128 a, v128 b, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false, byte elements = 4) + { + if (Sse2.IsSse2Supported) + { + promiseNonZero |= constexpr.ALL_NEQ_PS(a, 0f, elements); + promisePositive |= constexpr.ALL_GT_PS(a, 0f, elements); + promiseNegative |= constexpr.ALL_LT_PS(a, 0f, elements); + promiseNotNanInf |= constexpr.ALL_NOTNAN_PS(a, elements) && constexpr.ALL_NOTNAN_PS(b, elements) && constexpr.ALL_NEQ_PS(a, float.PositiveInfinity, elements) && constexpr.ALL_NEQ_PS(a, float.NegativeInfinity, elements); + + v128 ONE = Sse2.set1_epi32(1); + + v128 isGreater = Sse.cmpgt_ps(a, b); + v128 areDifferent = Sse.cmpneq_ps(a, b); + v128 summand; + + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = setall_si128(); + } + else + { + if (Sse4_1.IsSse41Supported) + { + summand = Sse4_1.blendv_ps(ONE, setall_si128(), a); + } + else + { + summand = Sse2.or_si128(Sse2.srai_epi32(a, 31), ONE); + } + } + + if (!promiseNotNanInf) + { + v128 SIGNALING_EXPONENT = Sse2.set1_epi32(F32_SIGNALING_EXPONENT); + + v128 xInfinite = Sse2.cmpeq_epi32(SIGNALING_EXPONENT, Sse2.and_si128(SIGNALING_EXPONENT, a)); + v128 eitherNaN = Sse.cmpunord_ps(a, b); + + summand = ternarylogic_si128(eitherNaN, xInfinite, summand, TernaryOperation.OxO2); + a = Sse2.or_si128(a, eitherNaN); + } + } + else + { + v128 NEGATIVE_ZERO = Sse2.set1_epi32(unchecked((int)(1u << 31))); + v128 IF_ZERO = Sse2.set1_epi32(unchecked((int)0x8000_0002u)); + + v128 isNegativeZero = Sse2.cmpeq_epi32(NEGATIVE_ZERO, a); + v128 isPositiveZero = Sse2.cmpeq_epi32(Sse2.setzero_si128(), a); + v128 zeroMask = ternarylogic_si128(isNegativeZero, isPositiveZero, isGreater, TernaryOperation.Ox87); + + summand = ternarylogic_si128(ONE, Sse2.srai_epi32(a, 31), zeroMask, TernaryOperation.OxF8); + v128 aPart0 = ternarylogic_si128(a, isGreater, zeroMask, TernaryOperation.OxEO); + v128 aPart1 = ternarylogic_si128(zeroMask, IF_ZERO, isGreater, TernaryOperation.OxO8); + + if (promiseNotNanInf) + { + a = Sse2.or_si128(aPart0, aPart1); + } + else + { + v128 SIGNALING_EXPONENT = Sse2.set1_epi32(F32_SIGNALING_EXPONENT); + + v128 xInfinite = Sse2.cmpeq_epi32(SIGNALING_EXPONENT, Sse2.and_si128(SIGNALING_EXPONENT, a)); + v128 eitherNaN = Sse.cmpunord_ps(a, b); + + summand = ternarylogic_si128(eitherNaN, xInfinite, summand, TernaryOperation.OxO2); + a = ternarylogic_si128(eitherNaN, aPart0, aPart1, TernaryOperation.OxFE); + } + } + + summand = ternarylogic_si128(isGreater, summand, areDifferent, TernaryOperation.Ox78); + summand = Sse2.sub_epi32(summand, isGreater); + + if (promisePositive) + { + return Sse2.sub_epi32(a, summand); + } + else + { + return Sse2.add_epi32(a, summand); + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_toward_ps(v256 a, v256 b, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false) + { + if (Avx2.IsAvx2Supported) + { + promiseNonZero |= constexpr.ALL_NEQ_PS(a, 0f); + promisePositive |= constexpr.ALL_GT_PS(a, 0f); + promiseNegative |= constexpr.ALL_LT_PS(a, 0f); + promiseNotNanInf |= constexpr.ALL_NOTNAN_PS(a) && constexpr.ALL_NOTNAN_PS(b) && constexpr.ALL_NEQ_PS(a, float.PositiveInfinity) && constexpr.ALL_NEQ_PS(a, float.NegativeInfinity); + + v256 ONE = Avx.mm256_set1_epi32(1); + + v256 isGreater = Avx.mm256_cmp_ps(a, b, (int)Avx.CMP.GT_OQ); + v256 areDifferent = Avx.mm256_cmp_ps(a, b, (int)Avx.CMP.NEQ_OQ); + v256 summand; + + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = mm256_setall_si256(); + } + else + { + summand = Avx.mm256_blendv_ps(ONE, mm256_setall_si256(), a); + } + + if (!promiseNotNanInf) + { + v256 SIGNALING_EXPONENT = Avx.mm256_set1_epi32(F32_SIGNALING_EXPONENT); + + v256 xInfinite = Avx2.mm256_cmpeq_epi32(SIGNALING_EXPONENT, Avx2.mm256_and_si256(SIGNALING_EXPONENT, a)); + v256 eitherNaN = Avx.mm256_cmp_ps(a, b, (int)Avx.CMP.UNORD_Q); + + summand = mm256_ternarylogic_si256(eitherNaN, xInfinite, summand, TernaryOperation.OxO2); + a = Avx2.mm256_or_si256(a, eitherNaN); + } + } + else + { + v256 NEGATIVE_ZERO = Avx.mm256_set1_epi32(unchecked((int)(1u << 31))); + v256 IF_ZERO = Avx.mm256_set1_epi32(unchecked((int)0x8000_0002u)); + + v256 isNegativeZero = Avx2.mm256_cmpeq_epi32(NEGATIVE_ZERO, a); + v256 isPositiveZero = Avx2.mm256_cmpeq_epi32(Avx.mm256_setzero_si256(), a); + v256 zeroMask = mm256_ternarylogic_si256(isNegativeZero, isPositiveZero, isGreater, TernaryOperation.Ox87); + + summand = mm256_ternarylogic_si256(ONE, Avx2.mm256_srai_epi32(a, 31), zeroMask, TernaryOperation.OxF8); + v256 aPart0 = mm256_ternarylogic_si256(a, isGreater, zeroMask, TernaryOperation.OxEO); + v256 aPart1 = mm256_ternarylogic_si256(zeroMask, IF_ZERO, isGreater, TernaryOperation.OxO8); + + if (promiseNotNanInf) + { + a = Avx2.mm256_or_si256(aPart0, aPart1); + } + else + { + v256 SIGNALING_EXPONENT = Avx.mm256_set1_epi32(F32_SIGNALING_EXPONENT); + + v256 xInfinite = Avx2.mm256_cmpeq_epi32(SIGNALING_EXPONENT, Avx2.mm256_and_si256(SIGNALING_EXPONENT, a)); + v256 eitherNaN = Avx.mm256_cmp_ps(a, b, (int)Avx.CMP.UNORD_Q); + + summand = mm256_ternarylogic_si256(eitherNaN, xInfinite, summand, TernaryOperation.OxO2); + a = mm256_ternarylogic_si256(eitherNaN, aPart0, aPart1, TernaryOperation.OxFE); + } + } + + summand = mm256_ternarylogic_si256(isGreater, summand, areDifferent, TernaryOperation.Ox78); + summand = Avx2.mm256_sub_epi32(summand, isGreater); + + if (promisePositive) + { + return Avx2.mm256_sub_epi32(a, summand); + } + else + { + return Avx2.mm256_add_epi32(a, summand); + } + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 toward_pd(v128 a, v128 b, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false) + { + if (Sse2.IsSse2Supported) + { + promiseNonZero |= constexpr.ALL_NEQ_PD(a, 0f); + promisePositive |= constexpr.ALL_GT_PD(a, 0f); + promiseNegative |= constexpr.ALL_LT_PD(a, 0f); + promiseNotNanInf |= constexpr.ALL_NOTNAN_PD(a) && constexpr.ALL_NOTNAN_PD(b) && constexpr.ALL_NEQ_PD(a, double.PositiveInfinity) && constexpr.ALL_NEQ_PD(a, double.NegativeInfinity); + + v128 ONE = Sse2.set1_epi64x(1); + + v128 isGreater = Sse2.cmpgt_pd(a, b); + v128 areDifferent = Sse2.cmpneq_pd(a, b); + v128 summand; + + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = setall_si128(); + } + else + { + if (Sse4_1.IsSse41Supported) + { + summand = Sse4_1.blendv_pd(ONE, setall_si128(), a); + } + else + { + summand = Sse2.or_si128(srai_epi64(a, 63), ONE); + } + } + + if (!promiseNotNanInf) + { + v128 SIGNALING_EXPONENT = Sse2.set1_epi64x(F64_SIGNALING_EXPONENT); + + v128 xInfinite; + if (Sse4_1.IsSse41Supported) + { + xInfinite = Sse4_1.cmpeq_epi64(SIGNALING_EXPONENT, Sse2.and_si128(SIGNALING_EXPONENT, a)); + } + else + { + xInfinite = Sse2.shuffle_epi32(Sse2.cmpeq_epi32(SIGNALING_EXPONENT, Sse2.and_si128(SIGNALING_EXPONENT, a)), Sse.SHUFFLE(3, 3, 1, 1)); + } + + v128 eitherNaN = Sse2.cmpunord_pd(a, b); + + summand = ternarylogic_si128(eitherNaN, xInfinite, summand, TernaryOperation.OxO2); + a = Sse2.or_si128(a, eitherNaN); + } + } + else + { + v128 NEGATIVE_ZERO = Sse2.set1_epi64x(unchecked((long)(1ul << 63))); + v128 IF_ZERO = Sse2.set1_epi64x(unchecked((long)0x8000_0000_0000_0002ul)); + + v128 isNegativeZero = cmpeq_epi64(NEGATIVE_ZERO, a); + v128 isPositiveZero = cmpeq_epi64(Sse2.setzero_si128(), a); + v128 zeroMask = ternarylogic_si128(isNegativeZero, isPositiveZero, isGreater, TernaryOperation.Ox87); + + summand = ternarylogic_si128(ONE, srai_epi64(a, 63), zeroMask, TernaryOperation.OxF8); + v128 aPart0 = ternarylogic_si128(a, isGreater, zeroMask, TernaryOperation.OxEO); + v128 aPart1 = ternarylogic_si128(zeroMask, IF_ZERO, isGreater, TernaryOperation.OxO8); + + if (promiseNotNanInf) + { + a = Sse2.or_si128(aPart0, aPart1); + } + else + { + v128 SIGNALING_EXPONENT = Sse2.set1_epi64x(F64_SIGNALING_EXPONENT); + + v128 xInfinite; + if (Sse4_1.IsSse41Supported) + { + xInfinite = Sse4_1.cmpeq_epi64(SIGNALING_EXPONENT, Sse2.and_si128(SIGNALING_EXPONENT, a)); + } + else + { + xInfinite = Sse2.shuffle_epi32(Sse2.cmpeq_epi32(SIGNALING_EXPONENT, Sse2.and_si128(SIGNALING_EXPONENT, a)), Sse.SHUFFLE(3, 3, 1, 1)); + } + + v128 eitherNaN = Sse2.cmpunord_pd(a, b); + + summand = ternarylogic_si128(eitherNaN, xInfinite, summand, TernaryOperation.OxO2); + a = ternarylogic_si128(eitherNaN, aPart0, aPart1, TernaryOperation.OxFE); + } + } + + summand = ternarylogic_si128(isGreater, summand, areDifferent, TernaryOperation.Ox78); + summand = Sse2.sub_epi64(summand, isGreater); + + if (promisePositive) + { + return Sse2.sub_epi64(a, summand); + } + else + { + return Sse2.add_epi64(a, summand); + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_toward_pd(v256 a, v256 b, bool promiseNonZero = false, bool promisePositive = false, bool promiseNegative = false, bool promiseNotNanInf = false, byte elements = 4) + { + if (Avx2.IsAvx2Supported) + { + promiseNonZero |= constexpr.ALL_NEQ_PD(a, 0f, elements); + promisePositive |= constexpr.ALL_GT_PD(a, 0f, elements); + promiseNegative |= constexpr.ALL_LT_PD(a, 0f, elements); + promiseNotNanInf |= constexpr.ALL_NOTNAN_PD(a, elements) && constexpr.ALL_NOTNAN_PD(b, elements) && constexpr.ALL_NEQ_PD(a, double.PositiveInfinity, elements) && constexpr.ALL_NEQ_PD(a, double.NegativeInfinity, elements); + + v256 ONE = Avx.mm256_set1_epi64x(1); + + v256 isGreater = Avx.mm256_cmp_pd(a, b, (int)Avx.CMP.GT_OQ); + v256 areDifferent = Avx.mm256_cmp_pd(a, b, (int)Avx.CMP.NEQ_OQ); + v256 summand; + + if (promiseNonZero) + { + if (promisePositive | promiseNegative) + { + summand = mm256_setall_si256(); + } + else + { + summand = Avx.mm256_blendv_pd(ONE, mm256_setall_si256(), a); + } + + if (!promiseNotNanInf) + { + v256 SIGNALING_EXPONENT = Avx.mm256_set1_epi64x(F64_SIGNALING_EXPONENT); + + v256 xInfinite = Avx2.mm256_cmpeq_epi64(SIGNALING_EXPONENT, Avx2.mm256_and_si256(SIGNALING_EXPONENT, a)); + v256 eitherNaN = Avx.mm256_cmp_pd(a, b, (int)Avx.CMP.UNORD_Q); + + summand = mm256_ternarylogic_si256(eitherNaN, xInfinite, summand, TernaryOperation.OxO2); + a = Avx2.mm256_or_si256(a, eitherNaN); + } + } + else + { + v256 NEGATIVE_ZERO = Avx.mm256_set1_epi64x(unchecked((long)(1ul << 63))); + v256 IF_ZERO = Avx.mm256_set1_epi64x(unchecked((long)0x8000_0000_0000_0002ul)); + + v256 isNegativeZero = Avx2.mm256_cmpeq_epi64(NEGATIVE_ZERO, a); + v256 isPositiveZero = Avx2.mm256_cmpeq_epi64(Avx.mm256_setzero_si256(), a); + v256 zeroMask = mm256_ternarylogic_si256(isNegativeZero, isPositiveZero, isGreater, TernaryOperation.Ox87); + + summand = mm256_ternarylogic_si256(ONE, mm256_srai_epi64(a, 63), zeroMask, TernaryOperation.OxF8); + v256 aPart0 = mm256_ternarylogic_si256(a, isGreater, zeroMask, TernaryOperation.OxEO); + v256 aPart1 = mm256_ternarylogic_si256(zeroMask, IF_ZERO, isGreater, TernaryOperation.OxO8); + + if (promiseNotNanInf) + { + a = Avx2.mm256_or_si256(aPart0, aPart1); + } + else + { + v256 SIGNALING_EXPONENT = Avx.mm256_set1_epi64x(F64_SIGNALING_EXPONENT); + + v256 xInfinite = Avx2.mm256_cmpeq_epi64(SIGNALING_EXPONENT, Avx2.mm256_and_si256(SIGNALING_EXPONENT, a)); + v256 eitherNaN = Avx.mm256_cmp_pd(a, b, (int)Avx.CMP.UNORD_Q); + + summand = mm256_ternarylogic_si256(eitherNaN, xInfinite, summand, TernaryOperation.OxO2); + a = mm256_ternarylogic_si256(eitherNaN, aPart0, aPart1, TernaryOperation.OxFE); + } + } + + summand = mm256_ternarylogic_si256(isGreater, summand, areDifferent, TernaryOperation.Ox78); + summand = Avx2.mm256_sub_epi64(summand, isGreater); + + if (promisePositive) + { + return Avx2.mm256_sub_epi64(a, summand); + } + else + { + return Avx2.mm256_add_epi64(a, summand); + } + } + else throw new IllegalInstructionException(); + } + } + } + + + unsafe public static partial class maxmath + { + /// Returns the next closest to '' in the direction of ''. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt128 nexttoward(UInt128 from, UInt128 to) + { + return from - (UInt128)compareto(from, to); + } + + + /// Returns the next closest to '' in the direction of ''. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Int128 nexttoward(Int128 from, Int128 to) + { + return from - compareto(from, to); + } + + + /// Returns the next closest to '' in the direction of ''. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte nexttoward(byte from, byte to) + { + return (byte)(from - compareto(from, to)); + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte2 nexttoward(byte2 from, byte2 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epu8(from, to, 2); + } + else + { + return new byte2(nexttoward(from.x, to.x), + nexttoward(from.y, to.y)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte3 nexttoward(byte3 from, byte3 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epu8(from, to, 3); + } + else + { + return new byte3(nexttoward(from.x, to.x), + nexttoward(from.y, to.y), + nexttoward(from.z, to.z)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte4 nexttoward(byte4 from, byte4 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epu8(from, to, 4); + } + else + { + return new byte4(nexttoward(from.x, to.x), + nexttoward(from.y, to.y), + nexttoward(from.z, to.z), + nexttoward(from.w, to.w)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte8 nexttoward(byte8 from, byte8 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epu8(from, to, 8); + } + else + { + return new byte8(nexttoward(from.x0, to.x0), + nexttoward(from.x1, to.x1), + nexttoward(from.x2, to.x2), + nexttoward(from.x3, to.x3), + nexttoward(from.x4, to.x4), + nexttoward(from.x5, to.x5), + nexttoward(from.x6, to.x6), + nexttoward(from.x7, to.x7)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte16 nexttoward(byte16 from, byte16 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epu8(from, to, 16); + } + else + { + return new byte16(nexttoward(from.x0, to.x0), + nexttoward(from.x1, to.x1), + nexttoward(from.x2, to.x2), + nexttoward(from.x3, to.x3), + nexttoward(from.x4, to.x4), + nexttoward(from.x5, to.x5), + nexttoward(from.x6, to.x6), + nexttoward(from.x7, to.x7), + nexttoward(from.x8, to.x8), + nexttoward(from.x9, to.x9), + nexttoward(from.x10, to.x10), + nexttoward(from.x11, to.x11), + nexttoward(from.x12, to.x12), + nexttoward(from.x13, to.x13), + nexttoward(from.x14, to.x14), + nexttoward(from.x15, to.x15)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte32 nexttoward(byte32 from, byte32 to) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_toward_epu8(from, to); + } + else + { + return new byte32(nexttoward(from.v16_0, to.v16_0), + nexttoward(from.v16_16, to.v16_16)); + } + } + + + /// Returns the next closest to '' in the direction of ''. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte nexttoward(sbyte from, sbyte to) + { + return (sbyte)(from - compareto(from, to)); + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte2 nexttoward(sbyte2 from, sbyte2 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epi8(from, to, 2); + } + else + { + return new sbyte2(nexttoward(from.x, to.x), + nexttoward(from.y, to.y)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte3 nexttoward(sbyte3 from, sbyte3 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epi8(from, to, 3); + } + else + { + return new sbyte3(nexttoward(from.x, to.x), + nexttoward(from.y, to.y), + nexttoward(from.z, to.z)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte4 nexttoward(sbyte4 from, sbyte4 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epi8(from, to, 4); + } + else + { + return new sbyte4(nexttoward(from.x, to.x), + nexttoward(from.y, to.y), + nexttoward(from.z, to.z), + nexttoward(from.w, to.w)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte8 nexttoward(sbyte8 from, sbyte8 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epi8(from, to, 8); + } + else + { + return new sbyte8(nexttoward(from.x0, to.x0), + nexttoward(from.x1, to.x1), + nexttoward(from.x2, to.x2), + nexttoward(from.x3, to.x3), + nexttoward(from.x4, to.x4), + nexttoward(from.x5, to.x5), + nexttoward(from.x6, to.x6), + nexttoward(from.x7, to.x7)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte16 nexttoward(sbyte16 from, sbyte16 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epi8(from, to, 16); + } + else + { + return new sbyte16(nexttoward(from.x0, to.x0), + nexttoward(from.x1, to.x1), + nexttoward(from.x2, to.x2), + nexttoward(from.x3, to.x3), + nexttoward(from.x4, to.x4), + nexttoward(from.x5, to.x5), + nexttoward(from.x6, to.x6), + nexttoward(from.x7, to.x7), + nexttoward(from.x8, to.x8), + nexttoward(from.x9, to.x9), + nexttoward(from.x10, to.x10), + nexttoward(from.x11, to.x11), + nexttoward(from.x12, to.x12), + nexttoward(from.x13, to.x13), + nexttoward(from.x14, to.x14), + nexttoward(from.x15, to.x15)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte32 nexttoward(sbyte32 from, sbyte32 to) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_toward_epi8(from, to); + } + else + { + return new sbyte32(nexttoward(from.v16_0, to.v16_0), + nexttoward(from.v16_16, to.v16_16)); + } + } + + + /// Returns the next closest to '' in the direction of ''. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort nexttoward(ushort from, ushort to) + { + return (ushort)(from - compareto(from, to)); + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort2 nexttoward(ushort2 from, ushort2 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epu16(from, to, 2); + } + else + { + return new ushort2(nexttoward(from.x, to.x), + nexttoward(from.y, to.y)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort3 nexttoward(ushort3 from, ushort3 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epu16(from, to, 3); + } + else + { + return new ushort3(nexttoward(from.x, to.x), + nexttoward(from.y, to.y), + nexttoward(from.z, to.z)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort4 nexttoward(ushort4 from, ushort4 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epu16(from, to, 4); + } + else + { + return new ushort4(nexttoward(from.x, to.x), + nexttoward(from.y, to.y), + nexttoward(from.z, to.z), + nexttoward(from.w, to.w)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort8 nexttoward(ushort8 from, ushort8 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epu16(from, to, 8); + } + else + { + return new ushort8(nexttoward(from.x0, to.x0), + nexttoward(from.x1, to.x1), + nexttoward(from.x2, to.x2), + nexttoward(from.x3, to.x3), + nexttoward(from.x4, to.x4), + nexttoward(from.x5, to.x5), + nexttoward(from.x6, to.x6), + nexttoward(from.x7, to.x7)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort16 nexttoward(ushort16 from, ushort16 to) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_toward_epu16(from, to); + } + else + { + return new ushort16(nexttoward(from.v8_0, to.v8_0), + nexttoward(from.v8_8, to.v8_8)); + } + } + + + /// Returns the next closest to '' in the direction of ''. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short nexttoward(short from, short to) + { + return (short)(from - compareto(from, to)); + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short2 nexttoward(short2 from, short2 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epi16(from, to, 2); + } + else + { + return new short2(nexttoward(from.x, to.x), + nexttoward(from.y, to.y)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short3 nexttoward(short3 from, short3 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epi16(from, to, 3); + } + else + { + return new short3(nexttoward(from.x, to.x), + nexttoward(from.y, to.y), + nexttoward(from.z, to.z)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short4 nexttoward(short4 from, short4 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epi16(from, to, 4); + } + else + { + return new short4(nexttoward(from.x, to.x), + nexttoward(from.y, to.y), + nexttoward(from.z, to.z), + nexttoward(from.w, to.w)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short8 nexttoward(short8 from, short8 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epi16(from, to, 8); + } + else + { + return new short8(nexttoward(from.x0, to.x0), + nexttoward(from.x1, to.x1), + nexttoward(from.x2, to.x2), + nexttoward(from.x3, to.x3), + nexttoward(from.x4, to.x4), + nexttoward(from.x5, to.x5), + nexttoward(from.x6, to.x6), + nexttoward(from.x7, to.x7)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short16 nexttoward(short16 from, short16 to) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_toward_epi16(from, to); + } + else + { + return new short16(nexttoward(from.v8_0, to.v8_0), + nexttoward(from.v8_8, to.v8_8)); + } + } + + + /// Returns the next closest to '' in the direction of ''. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint nexttoward(uint from, uint to) + { + return from - (uint)compareto(from, to); + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint2 nexttoward(uint2 from, uint2 to) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt2(Xse.toward_epu32(RegisterConversion.ToV128(from), RegisterConversion.ToV128(to), 2)); + } + else + { + return new uint2(nexttoward(from.x, to.x), + nexttoward(from.y, to.y)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint3 nexttoward(uint3 from, uint3 to) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt3(Xse.toward_epu32(RegisterConversion.ToV128(from), RegisterConversion.ToV128(to), 3)); + } + else + { + return new uint3(nexttoward(from.x, to.x), + nexttoward(from.y, to.y), + nexttoward(from.z, to.z)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint4 nexttoward(uint4 from, uint4 to) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToUInt4(Xse.toward_epu32(RegisterConversion.ToV128(from), RegisterConversion.ToV128(to), 4)); + } + else + { + return new uint4(nexttoward(from.x, to.x), + nexttoward(from.y, to.y), + nexttoward(from.z, to.z), + nexttoward(from.w, to.w)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint8 nexttoward(uint8 from, uint8 to) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_toward_epu32(from, to); + } + else + { + return new uint8(nexttoward(from.v4_0, to.v4_0), + nexttoward(from.v4_4, to.v4_4)); + } + } + + + /// Returns the next closest to '' in the direction of ''. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int nexttoward(int from, int to) + { + return from - compareto(from, to); + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int2 nexttoward(int2 from, int2 to) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToInt2(Xse.toward_epi32(RegisterConversion.ToV128(from), RegisterConversion.ToV128(to), 2)); + } + else + { + return new int2(nexttoward(from.x, to.x), + nexttoward(from.y, to.y)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int3 nexttoward(int3 from, int3 to) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToInt3(Xse.toward_epi32(RegisterConversion.ToV128(from), RegisterConversion.ToV128(to), 3)); + } + else + { + return new int3(nexttoward(from.x, to.x), + nexttoward(from.y, to.y), + nexttoward(from.z, to.z)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int4 nexttoward(int4 from, int4 to) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToInt4(Xse.toward_epi32(RegisterConversion.ToV128(from), RegisterConversion.ToV128(to), 4)); + } + else + { + return new int4(nexttoward(from.x, to.x), + nexttoward(from.y, to.y), + nexttoward(from.z, to.z), + nexttoward(from.w, to.w)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int8 nexttoward(int8 from, int8 to) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_toward_epi32(from, to); + } + else + { + return new int8(nexttoward(from.v4_0, to.v4_0), + nexttoward(from.v4_4, to.v4_4)); + } + } + + + /// Returns the next closest to '' in the direction of ''. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong nexttoward(ulong from, ulong to) + { + return from - (ulong)compareto(from, to); + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong2 nexttoward(ulong2 from, ulong2 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epu64(from, to); + } + else + { + return new ulong2(nexttoward(from.x, to.x), + nexttoward(from.y, to.y)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong3 nexttoward(ulong3 from, ulong3 to) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_toward_epu64(from, to, 3); + } + else + { + return new ulong3(nexttoward(from.xy, to.xy), + nexttoward(from.z, to.z)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong4 nexttoward(ulong4 from, ulong4 to) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_toward_epu64(from, to, 4); + } + else + { + return new ulong4(nexttoward(from.xy, to.xy), + nexttoward(from.zw, to.zw)); + } + } + + + /// Returns the next closest to '' in the direction of ''. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long nexttoward(long from, long to) + { + return from - compareto(from, to); + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long2 nexttoward(long2 from, long2 to) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_epi64(from, to); + } + else + { + return new long2(nexttoward(from.x, to.x), + nexttoward(from.y, to.y)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long3 nexttoward(long3 from, long3 to) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_toward_epi64(from, to, 3); + } + else + { + return new long3(nexttoward(from.xy, to.xy), + nexttoward(from.z, to.z)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long4 nexttoward(long4 from, long4 to) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_toward_epi64(from, to, 4); + } + else + { + return new long4(nexttoward(from.xy, to.xy), + nexttoward(from.zw, to.zw)); + } + } + + + /// Returns the next closest to '' in the direction of ''. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either , or aswell as any '' that is . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quarter nexttoward(quarter from, quarter to, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return asquarter(Xse.toward_pq(Sse2.cvtsi32_si128(from.value), + Sse2.cvtsi32_si128(to.value), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 1).Byte0); + } + else + { + int isGreater = -tobyte(from > to); + int __x = assbyte(from); + int summand; + + if (optimizations.Promises(Promise.NonZero)) + { + if (optimizations.Promises(Promise.Positive) | optimizations.Promises(Promise.Negative)) + { + summand = 1; + } + else + { + summand = 1 | (__x >> 31); + } + } + else + { + int zeroMask = -tobyte(__x != unchecked((int)0xFFFF_FF80)) ^ (-tobyte(__x == 0) & isGreater); + summand = 1 | ((__x >> 31) & zeroMask); + __x = (__x & (isGreater | zeroMask)) | andnot(0x82 & isGreater, zeroMask); + } + + if (!optimizations.Promises(Promise.Unsafe0)) + { + int xNotInf = -tobyte((__x & quarter.SIGNALING_EXPONENT) != quarter.SIGNALING_EXPONENT); + int eitherNaN = -tobyte(((__x & 0x7F) > quarter.SIGNALING_EXPONENT) | ((assbyte(to) & 0x7F) > quarter.SIGNALING_EXPONENT)); + summand = andnot(summand & xNotInf, eitherNaN); + __x |= eitherNaN; + } + + summand = (summand ^ isGreater) - isGreater; + summand &= -tobyte(from != to); + + if (optimizations.Promises(Promise.Negative)) + { + return asquarter((byte)(__x - summand)); + } + else + { + return asquarter((byte)(__x + summand)); + } + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either , or aswell as any '' that is . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quarter2 nexttoward(quarter2 from, quarter2 to, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_pq(from, + to, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 2); + } + else + { + return new quarter2(nexttoward(from.x, to.x, optimizations), + nexttoward(from.y, to.y, optimizations)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either , or aswell as any '' that is . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quarter3 nexttoward(quarter3 from, quarter3 to, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_pq(from, + to, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 3); + } + else + { + return new quarter3(nexttoward(from.x, to.x, optimizations), + nexttoward(from.y, to.y, optimizations), + nexttoward(from.z, to.z, optimizations)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either , or aswell as any '' that is . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quarter4 nexttoward(quarter4 from, quarter4 to, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_pq(from, + to, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 4); + } + else + { + return new quarter4(nexttoward(from.x, to.x, optimizations), + nexttoward(from.y, to.y, optimizations), + nexttoward(from.z, to.z, optimizations), + nexttoward(from.w, to.w, optimizations)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either , or aswell as any '' that is . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quarter8 nexttoward(quarter8 from, quarter8 to, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_pq(from, + to, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0)); + } + else + { + return new quarter8(nexttoward(from.x0, to.x0, optimizations), + nexttoward(from.x1, to.x1, optimizations), + nexttoward(from.x2, to.x2, optimizations), + nexttoward(from.x3, to.x3, optimizations), + nexttoward(from.x4, to.x4, optimizations), + nexttoward(from.x5, to.x5, optimizations), + nexttoward(from.x6, to.x6, optimizations), + nexttoward(from.x7, to.x7, optimizations)); + } + } + + + /// Returns the next closest to '' in the direction of ''. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either half.PositiveInfinity, half.NegativeInfinity or half.NaN aswell as any '' that is half.NaN. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static half nexttoward(half from, half to, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return ashalf(Xse.toward_ph(RegisterConversion.ToV128(from), + RegisterConversion.ToV128(to), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 1).UShort0); + } + else + { + int isGreater = -tobyte(from.IsGreaterThan(to)); + int __x = asshort(from); + int summand; + + if (optimizations.Promises(Promise.NonZero)) + { + if (optimizations.Promises(Promise.Positive) | optimizations.Promises(Promise.Negative)) + { + summand = 1; + } + else + { + summand = 1 | (__x >> 31); + } + } + else + { + int zeroMask = -tobyte(__x != unchecked((int)0xFFFF_8000)) ^ (-tobyte(__x == 0) & isGreater); + summand = 1 | ((__x >> 31) & zeroMask); + __x = (__x & (isGreater | zeroMask)) | andnot(unchecked((int)0xFFFF_8002) & isGreater, zeroMask); + } + + if (!optimizations.Promises(Promise.Unsafe0)) + { + int xNotInf = -tobyte((__x & F16_SIGNALING_EXPONENT) != F16_SIGNALING_EXPONENT); + int eitherNaN = -tobyte(((__x & 0x7FFF) > F16_SIGNALING_EXPONENT) | ((asushort(to) & 0x7FFF) > F16_SIGNALING_EXPONENT)); + summand = andnot(summand & xNotInf, eitherNaN); + __x |= eitherNaN; + } + + summand = (summand ^ isGreater) - isGreater; + summand &= -tobyte(from.IsNotEqualTo(to)); + + if (optimizations.Promises(Promise.Negative)) + { + return ashalf((ushort)(__x - summand)); + } + else + { + return ashalf((ushort)(__x + summand)); + } + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either half.PositiveInfinity, half.NegativeInfinity or half.NaN aswell as any '' that is half.NaN. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static half2 nexttoward(half2 from, half2 to, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToHalf2(Xse.toward_ph(RegisterConversion.ToV128(from), + RegisterConversion.ToV128(to), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 2)); + } + else + { + return new half2(nexttoward(from.x, to.x, optimizations), + nexttoward(from.y, to.y, optimizations)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either half.PositiveInfinity, half.NegativeInfinity or half.NaN aswell as any '' that is half.NaN. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static half3 nexttoward(half3 from, half3 to, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToHalf3(Xse.toward_ph(RegisterConversion.ToV128(from), + RegisterConversion.ToV128(to), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 3)); + } + else + { + return new half3(nexttoward(from.x, to.x, optimizations), + nexttoward(from.y, to.y, optimizations), + nexttoward(from.z, to.z, optimizations)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either half.PositiveInfinity, half.NegativeInfinity or half.NaN aswell as any '' that is half.NaN. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static half4 nexttoward(half4 from, half4 to, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToHalf4(Xse.toward_ph(RegisterConversion.ToV128(from), + RegisterConversion.ToV128(to), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 4)); + } + else + { + return new half4(nexttoward(from.x, to.x, optimizations), + nexttoward(from.y, to.y, optimizations), + nexttoward(from.z, to.z, optimizations), + nexttoward(from.w, to.w, optimizations)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either half.PositiveInfinity, half.NegativeInfinity or half.NaN aswell as any '' that is half.NaN. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static half8 nexttoward(half8 from, half8 to, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_ph(from, + to, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0)); + } + else + { + return new half8(nexttoward(from.x0, to.x0, optimizations), + nexttoward(from.x1, to.x1, optimizations), + nexttoward(from.x2, to.x2, optimizations), + nexttoward(from.x3, to.x3, optimizations), + nexttoward(from.x4, to.x4, optimizations), + nexttoward(from.x5, to.x5, optimizations), + nexttoward(from.x6, to.x6, optimizations), + nexttoward(from.x7, to.x7, optimizations)); + } + } + + + /// Returns the next closest to '' in the direction of ''. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either , or aswell as any '' that is . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float nexttoward(float from, float to, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_ps(RegisterConversion.ToV128(from), + RegisterConversion.ToV128(to), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 1).Float0; + } + else + { + int isGreater = -tobyte(from > to); + int __x = math.asint(from); + int summand; + + if (optimizations.Promises(Promise.NonZero)) + { + if (optimizations.Promises(Promise.Positive) | optimizations.Promises(Promise.Negative)) + { + summand = 1; + } + else + { + summand = 1 | (__x >> 31); + } + } + else + { + int zeroMask = -tobyte(__x != 1 << 31) ^ (-tobyte(__x == 0) & isGreater); + summand = 1 | ((__x >> 31) & zeroMask); + __x = (__x & (isGreater | zeroMask)) | (int)andnot(0x8000_0002u & isGreater, (uint)zeroMask); + } + + if (!optimizations.Promises(Promise.Unsafe0)) + { + int xNotInf = -tobyte((__x & F32_SIGNALING_EXPONENT) != F32_SIGNALING_EXPONENT); + int eitherNaN = -tobyte(((__x & 0x7FFF_FFFF) > F32_SIGNALING_EXPONENT) | ((math.asint(to) & 0x7FFF_FFFF) > F32_SIGNALING_EXPONENT)); + summand = andnot(summand & xNotInf, eitherNaN); + __x |= eitherNaN; + } + + summand = (summand ^ isGreater) - isGreater; + summand &= -tobyte(from != to); + + if (optimizations.Promises(Promise.Negative)) + { + return math.asfloat(__x - summand); + } + else + { + return math.asfloat(__x + summand); + } + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either , or aswell as any '' that is . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float2 nexttoward(float2 from, float2 to, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToFloat2(Xse.toward_ps(RegisterConversion.ToV128(from), + RegisterConversion.ToV128(to), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 2)); + } + else + { + return new float2(nexttoward(from.x, to.x, optimizations), + nexttoward(from.y, to.y, optimizations)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either , or aswell as any '' that is . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 nexttoward(float3 from, float3 to, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToFloat3(Xse.toward_ps(RegisterConversion.ToV128(from), + RegisterConversion.ToV128(to), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 3)); + } + else + { + return new float3(nexttoward(from.x, to.x, optimizations), + nexttoward(from.y, to.y, optimizations), + nexttoward(from.z, to.z, optimizations)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either , or aswell as any '' that is . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float4 nexttoward(float4 from, float4 to, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToFloat4(Xse.toward_ps(RegisterConversion.ToV128(from), + RegisterConversion.ToV128(to), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 4)); + } + else + { + return new float4(nexttoward(from.x, to.x, optimizations), + nexttoward(from.y, to.y, optimizations), + nexttoward(from.z, to.z, optimizations), + nexttoward(from.w, to.w, optimizations)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either , or aswell as any '' that is . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float8 nexttoward(float8 from, float8 to, Promise optimizations = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_toward_ps(from, + to, + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0)); + } + else + { + return new float8(nexttoward(from.v4_0, to.v4_0, optimizations), + nexttoward(from.v4_4, to.v4_4, optimizations)); + } + } + + + /// Returns the next closest to '' in the direction of ''. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either , or aswell as any '' that is . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double nexttoward(double from, double to, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return Xse.toward_pd(RegisterConversion.ToV128(from), + RegisterConversion.ToV128(to), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0)).Double0; + } + else + { + long isGreater = -(long)tobyte(from > to); + long __x = math.aslong(from); + long summand; + + if (optimizations.Promises(Promise.NonZero)) + { + if (optimizations.Promises(Promise.Positive) | optimizations.Promises(Promise.Negative)) + { + summand = 1; + } + else + { + summand = 1 | (__x >> 63); + } + } + else + { + long zeroMask = -(long)tobyte(__x != 1L << 63) ^ (-(long)tobyte(__x == 0) & isGreater); + summand = 1 | ((__x >> 63) & zeroMask); + __x = (__x & (isGreater | zeroMask)) | (long)andnot(0x8000_0000_0000_0002ul & (ulong)isGreater, (ulong)zeroMask); + } + + if (!optimizations.Promises(Promise.Unsafe0)) + { + long xNotInf = -(long)tobyte((__x & F64_SIGNALING_EXPONENT) != F64_SIGNALING_EXPONENT); + long eitherNaN = -(long)tobyte(((__x & 0x7FFF_FFFF_FFFF_FFFF) > F64_SIGNALING_EXPONENT) | ((math.aslong(to) & 0x7FFF_FFFF_FFFF_FFFF) > F64_SIGNALING_EXPONENT)); + summand = andnot(summand & xNotInf, eitherNaN); + __x |= eitherNaN; + } + + summand = (summand ^ isGreater) - isGreater; + summand &= -(long)tobyte(from != to); + + if (optimizations.Promises(Promise.Negative)) + { + return math.asdouble(__x - summand); + } + else + { + return math.asdouble(__x + summand); + } + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either , or aswell as any '' that is . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double2 nexttoward(double2 from, double2 to, Promise optimizations = Promise.Nothing) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToDouble2(Xse.toward_pd(RegisterConversion.ToV128(from), + RegisterConversion.ToV128(to), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0))); + } + else + { + return new double2(nexttoward(from.x, to.x, optimizations), + nexttoward(from.y, to.y, optimizations)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either , or aswell as any '' that is . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double3 nexttoward(double3 from, double3 to, Promise optimizations = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return RegisterConversion.ToDouble3(Xse.mm256_toward_pd(RegisterConversion.ToV256(from), + RegisterConversion.ToV256(to), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 3)); + } + else + { + return new double3(nexttoward(from.xy, to.xy, optimizations), + nexttoward(from.z, to.z, optimizations)); + } + } + + /// Returns a , where each component is the next closest to the corresponding '' component in the direction of the corresponding '' component. + /// + /// A "" with its flag set returns incorrect results for any '' that is negative 0. + /// A "" with its flag set returns incorrect results for any '' that is negative or 0. + /// A "" with its flag set returns incorrect results for any '' that is positive or 0. + /// A "" with its flag set returns incorrect results for any '' that is either , or aswell as any '' that is . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double4 nexttoward(double4 from, double4 to, Promise optimizations = Promise.Nothing) + { + if (Avx2.IsAvx2Supported) + { + return RegisterConversion.ToDouble4(Xse.mm256_toward_pd(RegisterConversion.ToV256(from), + RegisterConversion.ToV256(to), + promiseNonZero: optimizations.Promises(Promise.NonZero), + promiseNegative: optimizations.Promises(Promise.Negative), + promisePositive: optimizations.Promises(Promise.Positive), + promiseNotNanInf: optimizations.Promises(Promise.Unsafe0), + elements: 4)); + } + else + { + return new double4(nexttoward(from.xy, to.xy, optimizations), + nexttoward(from.zw, to.zw, optimizations)); + } + } + } +} diff --git a/Runtime/Math Lib/Functions/Arithmetic/Next Toward.cs.meta b/Runtime/Math Lib/Functions/Arithmetic/Next Toward.cs.meta new file mode 100644 index 0000000..ad40c7f --- /dev/null +++ b/Runtime/Math Lib/Functions/Arithmetic/Next Toward.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f896ced21b6058846a156f0e0f88957d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Add.cs b/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Add.cs index f7f8d7d..febc3f6 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Add.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Add.cs @@ -16,6 +16,14 @@ public static v128 adds_epu32(v128 a, v128 b, byte elements = 4) { if (Sse2.IsSse2Supported) { + if (constexpr.ALL_EQ_EPU32(b, 1, elements)) + { + v128 ALL_ONES = setall_si128(); + v128 isMaxValue = Sse2.cmpeq_epi32(a, ALL_ONES); + + return Sse2.sub_epi32(a, Sse2.andnot_si128(isMaxValue, ALL_ONES)); + } + v128 sum = Sse2.add_epi32(a, b); v128 overflowMask = cmpgt_epu32(b, sum, elements); @@ -29,6 +37,14 @@ public static v256 mm256_adds_epu32(v256 a, v256 b) { if (Avx2.IsAvx2Supported) { + if (constexpr.ALL_EQ_EPU32(b, 1)) + { + v256 ALL_ONES = mm256_setall_si256(); + v256 isMaxValue = Avx2.mm256_cmpeq_epi32(a, ALL_ONES); + + return Avx2.mm256_sub_epi32(a, Avx2.mm256_andnot_si256(isMaxValue, ALL_ONES)); + } + v256 sum = Avx2.mm256_add_epi32(a, b); v256 overflowMask = mm256_cmpgt_epu32(b, sum); @@ -42,6 +58,14 @@ public static v128 adds_epu64(v128 a, v128 b) { if (Sse2.IsSse2Supported) { + if (constexpr.ALL_EQ_EPU64(b, 1)) + { + v128 ALL_ONES = setall_si128(); + v128 isMaxValue = cmpeq_epi64(a, ALL_ONES); + + return Sse2.sub_epi64(a, Sse2.andnot_si128(isMaxValue, ALL_ONES)); + } + v128 sum = Sse2.add_epi64(a, b); v128 overflowMask = cmpgt_epu64(b, sum); @@ -51,10 +75,18 @@ public static v128 adds_epu64(v128 a, v128 b) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v256 mm256_adds_epu64(v256 a, v256 b) + public static v256 mm256_adds_epu64(v256 a, v256 b, byte elements = 4) { if (Avx2.IsAvx2Supported) { + if (constexpr.ALL_EQ_EPU64(b, 1, elements)) + { + v256 ALL_ONES = mm256_setall_si256(); + v256 isMaxValue = Avx2.mm256_cmpeq_epi64(a, ALL_ONES); + + return Avx2.mm256_sub_epi64(a, Avx2.mm256_andnot_si256(isMaxValue, ALL_ONES)); + } + v256 sum = Avx2.mm256_add_epi64(a, b); v256 overflowMask = mm256_cmpgt_epu64(a, sum); @@ -64,19 +96,35 @@ public static v256 mm256_adds_epu64(v256 a, v256 b) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v128 adds_epi32(v128 a, v128 b) + public static v128 adds_epi32(v128 a, v128 b, byte elements = 4) { if (Sse2.IsSse2Supported) { v128 MAX_VALUE = new v128(int.MaxValue); + + + if (constexpr.ALL_EQ_EPI32(b, -1, elements)) + { + return Sse2.add_epi32(a, Sse2.cmpgt_epi32(a, Sse2.set1_epi32(int.MinValue))); + } + if (constexpr.ALL_EQ_EPI32(b, 1, elements)) + { + return Sse2.sub_epi32(a, Sse2.cmpgt_epi32(MAX_VALUE, a)); + } + - v128 x_negative_mask = Sse2.srai_epi32(a, 31); - v128 ret = Sse2.sub_epi32(MAX_VALUE, x_negative_mask); - v128 cmp = Sse2.sub_epi32(ret, a); - - x_negative_mask = Sse2.cmpeq_epi32(x_negative_mask, Sse2.cmpgt_epi32(b, cmp)); - - return blendv_si128(ret, Sse2.add_epi32(a, b), x_negative_mask); + v128 result = Sse2.add_epi32(a, b); + v128 overflow = Sse2.add_epi32(MAX_VALUE, Sse2.srli_epi32(a, 31)); + v128 selectResult = ternarylogic_si128(overflow, b, result, TernaryOperation.OxBD); + + if (Sse4_1.IsSse41Supported) + { + return Sse4_1.blendv_ps(overflow, result, selectResult); + } + else + { + return blendv_si128(overflow, result, Sse2.srai_epi32(selectResult, 31)); + } } else throw new IllegalInstructionException(); } @@ -87,14 +135,23 @@ public static v256 mm256_adds_epi32(v256 a, v256 b) if (Avx2.IsAvx2Supported) { v256 MAX_VALUE = new v256(int.MaxValue); + + + if (constexpr.ALL_EQ_EPI32(b, -1)) + { + return Avx2.mm256_add_epi32(a, Avx2.mm256_cmpgt_epi32(a, Avx.mm256_set1_epi32(int.MinValue))); + } + if (constexpr.ALL_EQ_EPI32(b, 1)) + { + return Avx2.mm256_sub_epi32(a, Avx2.mm256_cmpgt_epi32(MAX_VALUE, a)); + } + - v256 x_negative_mask = Avx2.mm256_srai_epi32(a, 31); - v256 ret = Avx2.mm256_sub_epi32(MAX_VALUE, x_negative_mask); - v256 cmp = Avx2.mm256_sub_epi32(ret, a); - - x_negative_mask = Avx2.mm256_cmpeq_epi32(x_negative_mask, Avx2.mm256_cmpgt_epi32(b, cmp)); - - return mm256_blendv_si256(ret, Avx2.mm256_add_epi32(a, b), x_negative_mask); + v256 result = Avx2.mm256_add_epi32(a, b); + v256 overflow = Avx2.mm256_add_epi32(MAX_VALUE, Avx2.mm256_srli_epi32(a, 31)); + v256 selectResult = mm256_ternarylogic_si256(overflow, b, result, TernaryOperation.OxBD); + + return Avx.mm256_blendv_ps(overflow, result, selectResult); } else throw new IllegalInstructionException(); } @@ -105,14 +162,30 @@ public static v128 adds_epi64(v128 a, v128 b) if (Sse2.IsSse2Supported) { v128 MAX_VALUE = new v128(long.MaxValue); + + + if (constexpr.ALL_EQ_EPI64(b, -1)) + { + return Sse2.add_epi64(a, cmpgt_epi64(a, Sse2.set1_epi64x(long.MinValue))); + } + if (constexpr.ALL_EQ_EPI64(b, 1)) + { + return Sse2.sub_epi64(a, cmpgt_epi64(MAX_VALUE, a)); + } + - v128 x_negative_mask = srai_epi64(a, 63); - v128 ret = Sse2.sub_epi64(MAX_VALUE, x_negative_mask); - v128 cmp = Sse2.sub_epi64(ret, a); - - x_negative_mask = Sse2.cmpeq_epi32(x_negative_mask, cmpgt_epi64(b, cmp)); - - return blendv_si128(ret, Sse2.add_epi64(a, b), x_negative_mask); + v128 result = Sse2.add_epi64(a, b); + v128 overflow = Sse2.add_epi64(MAX_VALUE, Sse2.srli_epi64(a, 63)); + v128 selectResult = ternarylogic_si128(overflow, b, result, TernaryOperation.OxBD); + + if (Sse4_1.IsSse41Supported) + { + return Sse4_1.blendv_pd(overflow, result, selectResult); + } + else + { + return blendv_si128(overflow, result, srai_epi64(selectResult, 63)); + } } else throw new IllegalInstructionException(); } @@ -124,13 +197,22 @@ public static v256 mm256_adds_epi64(v256 a, v256 b, byte elements = 4) { v256 MAX_VALUE = new v256(long.MaxValue); - v256 x_negative_mask = mm256_srai_epi64(a, 63); - v256 ret = Avx2.mm256_sub_epi64(MAX_VALUE, x_negative_mask); - v256 cmp = Avx2.mm256_sub_epi64(ret, a); + + if (constexpr.ALL_EQ_EPI64(b, -1, elements)) + { + return Avx2.mm256_add_epi64(a, Avx2.mm256_cmpgt_epi64(a, Avx.mm256_set1_epi64x(long.MinValue))); + } + if (constexpr.ALL_EQ_EPI64(b, 1, elements)) + { + return Avx2.mm256_sub_epi64(a, Avx2.mm256_cmpgt_epi64(MAX_VALUE, a)); + } - x_negative_mask = Avx2.mm256_cmpeq_epi64(x_negative_mask, Xse.mm256_cmpgt_epi64(b, cmp, elements)); - - return mm256_blendv_si256(ret, Avx2.mm256_add_epi64(a, b), x_negative_mask); + + v256 result = Avx2.mm256_add_epi64(a, b); + v256 overflow = Avx2.mm256_add_epi64(MAX_VALUE, Avx2.mm256_srli_epi64(a, 63)); + v256 selectResult = mm256_ternarylogic_si256(overflow, b, result, TernaryOperation.OxBD); + + return Avx.mm256_blendv_pd(overflow, result, selectResult); } else throw new IllegalInstructionException(); } @@ -148,6 +230,14 @@ public static UInt128 addsaturated(UInt128 x, UInt128 y) { return x + y; } + if (Xse.constexpr.IS_TRUE(x == 1)) + { + return nextgreater(y); + } + if (Xse.constexpr.IS_TRUE(y == 1)) + { + return nextgreater(x); + } UInt128 res = x + y; bool overflow = res < x; @@ -159,15 +249,15 @@ public static UInt128 addsaturated(UInt128 x, UInt128 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Int128 addsaturated(Int128 x, Int128 y) { - Int128 ret = Int128.MaxValue + (x.hi64 >> 63); - Int128 cmp = ret - x; - - if ((x < 0) == (y > cmp)) - { - ret = x + y; - } - - return ret; + Int128 result = x + y; + Int128 overflow = (x.hi64 >> 63) + Int128.MaxValue; + + if ((long)((overflow ^ y) | ~(y ^ result)).hi64 >= 0) + { + result = overflow; + } + + return result; } @@ -179,6 +269,14 @@ public static byte addsaturated(byte x, byte y) { return (byte)(x + y); } + if (Xse.constexpr.IS_TRUE(x == 1)) + { + return nextgreater(y); + } + if (Xse.constexpr.IS_TRUE(y == 1)) + { + return nextgreater(x); + } byte temp = (byte)(x + y); @@ -307,6 +405,14 @@ public static ushort addsaturated(ushort x, ushort y) { return (ushort)(x + y); } + if (Xse.constexpr.IS_TRUE(x == 1)) + { + return nextgreater(y); + } + if (Xse.constexpr.IS_TRUE(y == 1)) + { + return nextgreater(x); + } ushort temp = (ushort)(x + y); @@ -406,6 +512,14 @@ public static uint addsaturated(uint x, uint y) { return x + y; } + if (Xse.constexpr.IS_TRUE(x == 1)) + { + return nextgreater(y); + } + if (Xse.constexpr.IS_TRUE(y == 1)) + { + return nextgreater(x); + } uint temp = x + y; @@ -418,7 +532,7 @@ public static uint2 addsaturated(uint2 x, uint2 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.adds_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 2)); + return RegisterConversion.ToUInt2(Xse.adds_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 2)); } else { @@ -433,7 +547,7 @@ public static uint3 addsaturated(uint3 x, uint3 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.adds_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 3)); + return RegisterConversion.ToUInt3(Xse.adds_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 3)); } else { @@ -449,7 +563,7 @@ public static uint4 addsaturated(uint4 x, uint4 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.adds_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 4)); + return RegisterConversion.ToUInt4(Xse.adds_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 4)); } else { @@ -484,6 +598,14 @@ public static ulong addsaturated(ulong x, ulong y) { return x + y; } + if (Xse.constexpr.IS_TRUE(x == 1)) + { + return nextgreater(y); + } + if (Xse.constexpr.IS_TRUE(y == 1)) + { + return nextgreater(x); + } ulong temp = x + y; @@ -511,7 +633,7 @@ public static ulong3 addsaturated(ulong3 x, ulong3 y) { if (Avx2.IsAvx2Supported) { - return Xse.mm256_adds_epu64(x, y); + return Xse.mm256_adds_epu64(x, y, 3); } else { @@ -526,7 +648,7 @@ public static ulong4 addsaturated(ulong4 x, ulong4 y) { if (Avx2.IsAvx2Supported) { - return Xse.mm256_adds_epu64(x, y); + return Xse.mm256_adds_epu64(x, y, 4); } else { @@ -786,7 +908,7 @@ public static int2 addsaturated(int2 x, int2 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.adds_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); + return RegisterConversion.ToInt2(Xse.adds_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 2)); } else { @@ -801,7 +923,7 @@ public static int3 addsaturated(int3 x, int3 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.adds_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); + return RegisterConversion.ToInt3(Xse.adds_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 3)); } else { @@ -817,7 +939,7 @@ public static int4 addsaturated(int4 x, int4 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.adds_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); + return RegisterConversion.ToInt4(Xse.adds_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 4)); } else { @@ -848,15 +970,15 @@ public static int8 addsaturated(int8 x, int8 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long addsaturated(long x, long y) { - long ret = long.MaxValue - (x >> 63); - long cmp = ret - x; - - if ((x < 0) == (y > cmp)) - { - ret = x + y; - } - - return ret; + long result = x + y; + long overflow = (long)((ulong)x >> 63) + long.MaxValue; + + if ((long)((overflow ^ y) | ~(y ^ result)) >= 0) + { + result = overflow; + } + + return result; } /// Adds each component of and and returns the results, which are clamped to if overflow occurs or if underflow occurs. diff --git a/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Cast.cs b/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Cast.cs index a311d71..d91fcd9 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Cast.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Cast.cs @@ -3059,7 +3059,7 @@ public static uint2 touintsaturated(long2 x) { v128 clamped = clamp(x, uint.MinValue, uint.MaxValue); - return RegisterConversion.ToType(Xse.cvtepi64_epi32(clamped)); + return RegisterConversion.ToUInt2(Xse.cvtepi64_epi32(clamped)); } else { @@ -3075,7 +3075,7 @@ public static uint3 touintsaturated(long3 x) { v256 clamped = clamp(x, uint.MinValue, uint.MaxValue); - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi32(clamped)); + return RegisterConversion.ToUInt3(Xse.mm256_cvtepi64_epi32(clamped)); } else { @@ -3091,7 +3091,7 @@ public static uint4 touintsaturated(long4 x) { v256 clamped = clamp(x, uint.MinValue, uint.MaxValue); - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi32(clamped)); + return RegisterConversion.ToUInt4(Xse.mm256_cvtepi64_epi32(clamped)); } else { @@ -3127,7 +3127,7 @@ public static uint2 touintsaturated(ulong2 x) { v128 clamped = min(x, uint.MaxValue); - return RegisterConversion.ToType(Xse.cvtepi64_epi32(clamped)); + return RegisterConversion.ToUInt2(Xse.cvtepi64_epi32(clamped)); } else { @@ -3143,7 +3143,7 @@ public static uint3 touintsaturated(ulong3 x) { v256 clamped = min(x, uint.MaxValue); - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi32(clamped)); + return RegisterConversion.ToUInt3(Xse.mm256_cvtepi64_epi32(clamped)); } else { @@ -3159,7 +3159,7 @@ public static uint4 touintsaturated(ulong4 x) { v256 clamped = min(x, uint.MaxValue); - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi32(clamped)); + return RegisterConversion.ToUInt4(Xse.mm256_cvtepi64_epi32(clamped)); } else { @@ -3319,7 +3319,7 @@ public static uint8 touintsaturated(float8 x) v128 lo = Avx.mm256_castps256_ps128(result); v128 hi = Avx.mm256_extractf128_ps(result, 1); - return new uint8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + return new uint8(RegisterConversion.ToUInt4(lo), RegisterConversion.ToUInt4(hi)); } else { @@ -3458,7 +3458,7 @@ public static int2 tointsaturated(long2 x) { v128 clamped = clamp(x, int.MinValue, int.MaxValue); - return RegisterConversion.ToType(Xse.cvtepi64_epi32(clamped)); + return RegisterConversion.ToInt2(Xse.cvtepi64_epi32(clamped)); } else { @@ -3474,7 +3474,7 @@ public static int3 tointsaturated(long3 x) { v256 clamped = clamp(x, int.MinValue, int.MaxValue); - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi32(clamped)); + return RegisterConversion.ToInt3(Xse.mm256_cvtepi64_epi32(clamped)); } else { @@ -3490,7 +3490,7 @@ public static int4 tointsaturated(long4 x) { v256 clamped = clamp(x, int.MinValue, int.MaxValue); - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi32(clamped)); + return RegisterConversion.ToInt4(Xse.mm256_cvtepi64_epi32(clamped)); } else { @@ -3526,7 +3526,7 @@ public static int2 tointsaturated(ulong2 x) { v128 clamped = min(x, int.MaxValue); - return RegisterConversion.ToType(Xse.cvtepi64_epi32(clamped)); + return RegisterConversion.ToInt2(Xse.cvtepi64_epi32(clamped)); } else { @@ -3542,7 +3542,7 @@ public static int3 tointsaturated(ulong3 x) { v256 clamped = min(x, int.MaxValue); - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi32(clamped)); + return RegisterConversion.ToInt3(Xse.mm256_cvtepi64_epi32(clamped)); } else { @@ -3558,7 +3558,7 @@ public static int4 tointsaturated(ulong4 x) { v256 clamped = min(x, int.MaxValue); - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi32(clamped)); + return RegisterConversion.ToInt4(Xse.mm256_cvtepi64_epi32(clamped)); } else { @@ -3718,7 +3718,7 @@ public static int8 tointsaturated(float8 x) v128 lo = Avx.mm256_castps256_ps128(result); v128 hi = Avx.mm256_extractf128_ps(result, 1); - return new int8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + return new int8(RegisterConversion.ToInt4(lo), RegisterConversion.ToInt4(hi)); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Divide.cs b/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Divide.cs index 5534db7..7a30c70 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Divide.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Divide.cs @@ -303,7 +303,7 @@ public static int2 divsaturated(int2 x, int2 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.divs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 2)); + return RegisterConversion.ToInt2(Xse.divs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 2)); } else { @@ -318,7 +318,7 @@ public static int3 divsaturated(int3 x, int3 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.divs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 3)); + return RegisterConversion.ToInt3(Xse.divs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 3)); } else { @@ -334,7 +334,7 @@ public static int4 divsaturated(int4 x, int4 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.divs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 4)); + return RegisterConversion.ToInt4(Xse.divs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Multiply.cs b/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Multiply.cs index 2e2ebcf..6a58114 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Multiply.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Multiply.cs @@ -1476,7 +1476,7 @@ public static uint2 mulsaturated(uint2 x, uint2 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.muls_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); + return RegisterConversion.ToUInt2(Xse.muls_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); } else { @@ -1491,7 +1491,7 @@ public static uint3 mulsaturated(uint3 x, uint3 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.muls_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); + return RegisterConversion.ToUInt3(Xse.muls_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); } else { @@ -1507,7 +1507,7 @@ public static uint4 mulsaturated(uint4 x, uint4 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.muls_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); + return RegisterConversion.ToUInt4(Xse.muls_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); } else { @@ -1850,7 +1850,7 @@ public static int2 mulsaturated(int2 x, int2 y) { if (Sse4_1.IsSse41Supported) { - return RegisterConversion.ToType(Xse.muls_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 2)); + return RegisterConversion.ToInt2(Xse.muls_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 2)); } else { @@ -1865,7 +1865,7 @@ public static int3 mulsaturated(int3 x, int3 y) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.muls_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 3)); + return RegisterConversion.ToInt3(Xse.muls_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 3)); } else { @@ -1880,7 +1880,7 @@ public static int4 mulsaturated(int4 x, int4 y) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.muls_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 4)); + return RegisterConversion.ToInt4(Xse.muls_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Subtract.cs b/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Subtract.cs index ab2b33f..4f991cc 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Subtract.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Saturation/Saturation Subtract.cs @@ -16,6 +16,12 @@ public static v128 subs_epu32(v128 a, v128 b, byte elements = 4) { if (Sse2.IsSse2Supported) { + if (constexpr.ALL_EQ_EPU32(b, 1, elements)) + { + return Sse2.add_epi32(a, not_si128(Sse2.cmpeq_epi32(a, Sse2.setzero_si128()))); + } + + return Sse2.andnot_si128(cmpge_epu32(b, a, elements), Sse2.sub_epi32(a, b)); } else throw new IllegalInstructionException(); @@ -26,6 +32,12 @@ public static v256 mm256_subs_epu32(v256 a, v256 b) { if (Avx2.IsAvx2Supported) { + if (constexpr.ALL_EQ_EPU32(b, 1)) + { + return Avx2.mm256_add_epi32(a, mm256_not_si256(Avx2.mm256_cmpeq_epi32(a, Avx.mm256_setzero_si256()))); + } + + return Avx2.mm256_andnot_si256(mm256_cmpge_epu32(b, a), Avx2.mm256_sub_epi32(a, b)); } else throw new IllegalInstructionException(); @@ -36,35 +48,63 @@ public static v128 subs_epu64(v128 a, v128 b) { if (Sse2.IsSse2Supported) { + if (constexpr.ALL_EQ_EPU64(b, 1)) + { + return Sse2.add_epi64(a, not_si128(cmpeq_epi64(a, Sse2.setzero_si128()))); + } + + return Sse2.andnot_si128(cmpgt_epu64(b, a), Sse2.sub_epi64(a, b)); } else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v256 mm256_subs_epu64(v256 a, v256 b) + public static v256 mm256_subs_epu64(v256 a, v256 b, byte elements = 4) { if (Avx2.IsAvx2Supported) { + if (constexpr.ALL_EQ_EPU64(b, 1, elements)) + { + return Avx2.mm256_add_epi64(a, mm256_not_si256(Avx2.mm256_cmpeq_epi64(a, Avx.mm256_setzero_si256()))); + } + + return Avx2.mm256_andnot_si256(mm256_cmpgt_epu64(b, a), Avx2.mm256_sub_epi64(a, b)); } else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v128 subs_epi32(v128 a, v128 b) + public static v128 subs_epi32(v128 a, v128 b, byte elements = 4) { if (Sse2.IsSse2Supported) { - v128 MAX_VALUE = new v128(int.MaxValue); - - v128 x_negative_mask = Sse2.srai_epi32(a, 31); - v128 ret = Sse2.sub_epi32(MAX_VALUE, x_negative_mask); - v128 cmp = Sse2.add_epi32(ret, a); - - x_negative_mask = Sse2.cmpeq_epi32(Sse2.cmpgt_epi32(cmp, b), x_negative_mask); + v128 MAX_VALUE = Sse2.set1_epi32(int.MaxValue); + + + if (constexpr.ALL_EQ_EPI32(b, -1, elements)) + { + return Sse2.sub_epi32(a, Sse2.cmpgt_epi32(MAX_VALUE, a)); + } + if (constexpr.ALL_EQ_EPI32(b, 1, elements)) + { + return Sse2.add_epi32(a, Sse2.cmpgt_epi32(a, Sse2.set1_epi32(int.MinValue))); + } + - return Xse.blendv_si128(ret, Sse2.sub_epi32(a, b), x_negative_mask); + v128 result = Sse2.sub_epi32(a, b); + v128 overflow = Sse2.add_epi32(MAX_VALUE, Sse2.srli_epi32(a, 31)); + v128 selectOverflow = ternarylogic_si128(overflow, b, result, TernaryOperation.Ox18); + + if (Sse4_1.IsSse41Supported) + { + return Sse4_1.blendv_ps(result, overflow, selectOverflow); + } + else + { + return blendv_si128(result, overflow, Sse2.srai_epi32(selectOverflow, 63)); + } } else throw new IllegalInstructionException(); } @@ -74,15 +114,24 @@ public static v256 mm256_subs_epi32(v256 a, v256 b) { if (Avx2.IsAvx2Supported) { - v256 MAX_VALUE = new v256(int.MaxValue); - - v256 x_negative_mask = Avx2.mm256_srai_epi32(a, 31); - v256 ret = Avx2.mm256_sub_epi32(MAX_VALUE, x_negative_mask); - v256 cmp = Avx2.mm256_add_epi32(ret, a); - - x_negative_mask = Avx2.mm256_cmpeq_epi32(Avx2.mm256_cmpgt_epi32(cmp, b), x_negative_mask); + v256 MAX_VALUE = Avx.mm256_set1_epi32(int.MaxValue); + + + if (constexpr.ALL_EQ_EPI32(b, -1)) + { + return Avx2.mm256_sub_epi32(a, Avx2.mm256_cmpgt_epi32(MAX_VALUE, a)); + } + if (constexpr.ALL_EQ_EPI32(b, 1)) + { + return Avx2.mm256_add_epi32(a, Avx2.mm256_cmpgt_epi32(a, Avx.mm256_set1_epi32(int.MinValue))); + } + - return Xse.mm256_blendv_si256(ret, Avx2.mm256_sub_epi32(a, b), x_negative_mask); + v256 result = Avx2.mm256_sub_epi32(a, b); + v256 overflow = Avx2.mm256_add_epi32(MAX_VALUE, Avx2.mm256_srli_epi32(a, 31)); + v256 selectOverflow = mm256_ternarylogic_si256(overflow, b, result, TernaryOperation.Ox18); + + return Avx.mm256_blendv_ps(result, overflow, selectOverflow); } else throw new IllegalInstructionException(); } @@ -92,15 +141,31 @@ public static v128 subs_epi64(v128 a, v128 b) { if (Sse2.IsSse2Supported) { - v128 MAX_VALUE = new v128(long.MaxValue); + v128 MAX_VALUE = Sse2.set1_epi64x(long.MaxValue); + + + if (constexpr.ALL_EQ_EPI64(b, -1)) + { + return Sse2.sub_epi64(a, cmpgt_epi64(MAX_VALUE, a)); + } + if (constexpr.ALL_EQ_EPI64(b, 1)) + { + return Sse2.add_epi64(a, cmpgt_epi64(a, Sse2.set1_epi64x(long.MinValue))); + } + - v128 x_negative_mask = Xse.cmpgt_epi64(Sse2.setzero_si128(), a); - v128 ret = Sse2.sub_epi64(MAX_VALUE, x_negative_mask); - v128 cmp = Sse2.add_epi64(ret, a); - - x_negative_mask = Sse2.cmpeq_epi32(Xse.cmpgt_epi64(cmp, b), x_negative_mask); - - return Xse.blendv_si128(ret, Sse2.sub_epi64(a, b), x_negative_mask); + v128 result = Sse2.sub_epi64(a, b); + v128 overflow = Sse2.add_epi64(MAX_VALUE, Sse2.srli_epi64(a, 63)); + v128 selectOverflow = ternarylogic_si128(overflow, b, result, TernaryOperation.Ox18); + + if (Sse4_1.IsSse41Supported) + { + return Sse4_1.blendv_pd(result, overflow, selectOverflow); + } + else + { + return blendv_si128(result, overflow, srai_epi64(selectOverflow, 63)); + } } else throw new IllegalInstructionException(); } @@ -110,15 +175,24 @@ public static v256 mm256_subs_epi64(v256 a, v256 b, byte elements = 4) { if (Avx2.IsAvx2Supported) { - v256 MAX_VALUE = new v256(long.MaxValue); + v256 MAX_VALUE = Avx.mm256_set1_epi64x(long.MaxValue); + + + if (constexpr.ALL_EQ_EPI64(b, -1, elements)) + { + return Avx2.mm256_sub_epi64(a, Avx2.mm256_cmpgt_epi64(MAX_VALUE, a)); + } + if (constexpr.ALL_EQ_EPI64(b, 1, elements)) + { + return Avx2.mm256_add_epi64(a, Avx2.mm256_cmpgt_epi64(a, Avx.mm256_set1_epi64x(long.MinValue))); + } - v256 x_negative_mask = Xse.mm256_cmpgt_epi64(Avx.mm256_setzero_si256(), a, elements); - v256 ret = Avx2.mm256_sub_epi8(MAX_VALUE, x_negative_mask); - v256 cmp = Avx2.mm256_add_epi64(ret, a); - - x_negative_mask = Avx2.mm256_cmpeq_epi64(Xse.mm256_cmpgt_epi64(cmp, b, elements), x_negative_mask); - - return Xse.mm256_blendv_si256(ret, Avx2.mm256_sub_epi64(a, b), x_negative_mask); + + v256 result = Avx2.mm256_sub_epi64(a, b); + v256 overflow = Avx2.mm256_add_epi64(MAX_VALUE, Avx2.mm256_srli_epi64(a, 63)); + v256 selectOverflow = mm256_ternarylogic_si256(overflow, b, result, TernaryOperation.Ox18); + + return Avx.mm256_blendv_pd(result, overflow, selectOverflow); } else throw new IllegalInstructionException(); } @@ -132,15 +206,20 @@ unsafe public static partial class maxmath [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Int128 subsaturated(Int128 x, Int128 y) { - Int128 ret = Int128.MaxValue + tobyte((long)x.hi64 < 0); - Int128 cmp = ret + x; - - if ((x < 0) == (y < cmp)) + if (Xse.constexpr.IS_TRUE(y == 1)) { - ret = x - y; + return nextsmaller(x); } - - return ret; + + Int128 res = x - y; + Int128 overflow = (x.hi64 >> 63) + Int128.MaxValue; + + if ((long)((overflow ^ y) & (overflow ^ res)).hi64 < 0) + { + res = overflow; + } + + return res; } /// Subtracts from and returns the result, which is clamped to if underflow occurs. @@ -155,6 +234,11 @@ public static UInt128 subsaturated(UInt128 x, UInt128 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte subsaturated(byte x, byte y) { + if (Xse.constexpr.IS_TRUE(y == 1)) + { + return nextsmaller(x); + } + return (byte)(y >= x ? 0 : x - y); } @@ -276,6 +360,11 @@ public static byte32 subsaturated(byte32 x, byte32 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort subsaturated(ushort x, ushort y) { + if (Xse.constexpr.IS_TRUE(y == 1)) + { + return nextsmaller(x); + } + return (ushort)(y >= x ? 0 : x - y); } @@ -368,6 +457,11 @@ public static ushort16 subsaturated(ushort16 x, ushort16 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint subsaturated(uint x, uint y) { + if (Xse.constexpr.IS_TRUE(y == 1)) + { + return nextsmaller(x); + } + return y >= x ? 0 : x - y; } @@ -377,7 +471,7 @@ public static uint2 subsaturated(uint2 x, uint2 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.subs_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 2)); + return RegisterConversion.ToUInt2(Xse.subs_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 2)); } else { @@ -392,7 +486,7 @@ public static uint3 subsaturated(uint3 x, uint3 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.subs_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 3)); + return RegisterConversion.ToUInt3(Xse.subs_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 3)); } else { @@ -408,7 +502,7 @@ public static uint4 subsaturated(uint4 x, uint4 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.subs_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 4)); + return RegisterConversion.ToUInt4(Xse.subs_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 4)); } else { @@ -439,6 +533,11 @@ public static uint8 subsaturated(uint8 x, uint8 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong subsaturated(ulong x, ulong y) { + if (Xse.constexpr.IS_TRUE(y == 1)) + { + return nextsmaller(x); + } + return y >= x ? 0 : x - y; } @@ -463,7 +562,7 @@ public static ulong3 subsaturated(ulong3 x, ulong3 y) { if (Avx2.IsAvx2Supported) { - return Xse.mm256_subs_epu64(x, y); + return Xse.mm256_subs_epu64(x, y, 3); } else { @@ -478,7 +577,7 @@ public static ulong4 subsaturated(ulong4 x, ulong4 y) { if (Avx2.IsAvx2Supported) { - return Xse.mm256_subs_epu64(x, y); + return Xse.mm256_subs_epu64(x, y, 4); } else { @@ -738,7 +837,7 @@ public static int2 subsaturated(int2 x, int2 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.subs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); + return RegisterConversion.ToInt2(Xse.subs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 2)); } else { @@ -753,7 +852,7 @@ public static int3 subsaturated(int3 x, int3 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.subs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); + return RegisterConversion.ToInt3(Xse.subs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 3)); } else { @@ -769,7 +868,7 @@ public static int4 subsaturated(int4 x, int4 y) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.subs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); + return RegisterConversion.ToInt4(Xse.subs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 4)); } else { @@ -800,15 +899,15 @@ public static int8 subsaturated(int8 x, int8 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long subsaturated(long x, long y) { - long ret = long.MaxValue + tobyte(x < 0); - long cmp = ret + x; - - if ((x < 0) == (y < cmp)) - { - ret = x - y; - } - - return ret; + long result = x - y; + long overflow = (long)((ulong)x >> 63) + long.MaxValue; + + if (((overflow ^ y) & (overflow ^ result)) < 0) + { + result = overflow; + } + + return result; } /// Subtracts each component of from each component of and returns the results, which are clamped to if overflow occurs or if underflow occurs. diff --git a/Runtime/Math Lib/Functions/Arithmetic/Sign/Copy Sign.cs b/Runtime/Math Lib/Functions/Arithmetic/Sign/Copy Sign.cs index 0448e36..5b38b7d 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Sign/Copy Sign.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Sign/Copy Sign.cs @@ -20,11 +20,20 @@ public static v128 movsign_epi8(v128 a, v128 s, bool promise = false, byte eleme { s = Sse2.sub_epi8(s, Sse2.cmpeq_epi8(s, Sse2.setzero_si128())); } + else if (constexpr.ALL_EQ_EPI8(a, 1, elements) || constexpr.ALL_EQ_EPI8(a, -1, elements)) + { + return Sse2.or_si128(srai_epi8(s, 7), Sse2.set1_epi8(1)); + } return Ssse3.sign_epi8(abs_epi8(a, elements), s); } else if (Sse2.IsSse2Supported) { + if (constexpr.ALL_EQ_EPI8(a, 1, elements) || constexpr.ALL_EQ_EPI8(a, -1, elements)) + { + return Sse2.or_si128(srai_epi8(s, 7), Sse2.set1_epi8(1)); + } + v128 res = Sse2.xor_si128(a, s); res = srai_epi8(res, 7); @@ -42,6 +51,10 @@ public static v256 mm256_movsign_epi8(v256 a, v256 s, bool promise = false) { s = Avx2.mm256_sub_epi8(s, Avx2.mm256_cmpeq_epi8(s, Avx.mm256_setzero_si256())); } + else if (constexpr.ALL_EQ_EPI8(a, 1) || constexpr.ALL_EQ_EPI8(a, -1)) + { + return Avx2.mm256_or_si256(mm256_srai_epi8(s, 7), Avx.mm256_set1_epi8(1)); + } return Avx2.mm256_sign_epi8(mm256_abs_epi8(a), s); } @@ -52,28 +65,30 @@ public static v256 mm256_movsign_epi8(v256 a, v256 s, bool promise = false) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v128 movsign_epi16(v128 a, v128 s, bool promise = false, byte elements = 8) { - if (Sse2.IsSse2Supported) + if (Ssse3.IsSsse3Supported) { - if (constexpr.ALL_EQ_EPI16(a, 1, elements) || constexpr.ALL_EQ_EPI16(a, -1, elements)) + if (!(promise || constexpr.ALL_NEQ_EPI16(s, 0, elements))) { - return Sse2.or_si128(Sse2.set1_epi16(1), Sse2.srai_epi16(s, 15)); + s = Sse2.sub_epi16(s, Sse2.cmpeq_epi16(s, Sse2.setzero_si128())); } - else if (Ssse3.IsSsse3Supported) + else if (constexpr.ALL_EQ_EPI16(a, 1, elements) || constexpr.ALL_EQ_EPI16(a, -1, elements)) { - if (!(promise || constexpr.ALL_NEQ_EPI16(s, 0, elements))) - { - s = Sse2.sub_epi16(s, Sse2.cmpeq_epi16(s, Sse2.setzero_si128())); - } - - return Ssse3.sign_epi16(abs_epi16(a, elements), s); + return Sse2.or_si128(srai_epi16(s, 15), Sse2.set1_epi16(1)); } - else - { - v128 res = Sse2.xor_si128(a, s); - res = Sse2.srai_epi16(res, 15); - return Sse2.sub_epi16(Sse2.xor_si128(a, res), res); + return Ssse3.sign_epi16(abs_epi16(a, elements), s); + } + else if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_EQ_EPI16(a, 1, elements) || constexpr.ALL_EQ_EPI16(a, -1, elements)) + { + return Sse2.or_si128(srai_epi16(s, 15), Sse2.set1_epi16(1)); } + + v128 res = Sse2.xor_si128(a, s); + res = Sse2.srai_epi16(res, 15); + + return Sse2.sub_epi16(Sse2.xor_si128(a, res), res); } else throw new IllegalInstructionException(); } @@ -83,19 +98,16 @@ public static v256 mm256_movsign_epi16(v256 a, v256 s, bool promise = false) { if (Avx2.IsAvx2Supported) { - if (constexpr.ALL_EQ_EPI16(a, 1) || constexpr.ALL_EQ_EPI16(a, -1)) + if (!(promise || constexpr.ALL_NEQ_EPI16(s, 0))) { - return Avx2.mm256_or_si256(Avx.mm256_set1_epi16(1), Avx2.mm256_srai_epi16(s, 15)); + s = Avx2.mm256_sub_epi16(s, Avx2.mm256_cmpeq_epi16(s, Avx.mm256_setzero_si256())); } - else + else if (constexpr.ALL_EQ_EPI16(a, 1) || constexpr.ALL_EQ_EPI16(a, -1)) { - if (!(promise || constexpr.ALL_NEQ_EPI16(s, 0))) - { - s = Avx2.mm256_sub_epi16(s, Avx2.mm256_cmpeq_epi16(s, Avx.mm256_setzero_si256())); - } - - return Avx2.mm256_sign_epi16(mm256_abs_epi16(a), s); + return Avx2.mm256_or_si256(mm256_srai_epi16(s, 15), Avx.mm256_set1_epi16(1)); } + + return Avx2.mm256_sign_epi16(mm256_abs_epi16(a), s); } else throw new IllegalInstructionException(); } @@ -104,28 +116,30 @@ public static v256 mm256_movsign_epi16(v256 a, v256 s, bool promise = false) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v128 movsign_epi32(v128 a, v128 s, bool promise = false, byte elements = 4) { - if (Sse2.IsSse2Supported) + if (Ssse3.IsSsse3Supported) { - if (constexpr.ALL_EQ_EPI32(a, 1, elements) || constexpr.ALL_EQ_EPI32(a, -1, elements)) + if (!(promise || constexpr.ALL_NEQ_EPI32(s, 0, elements))) { - return Sse2.or_si128(Sse2.set1_epi32(1), Sse2.srai_epi32(s, 31)); + s = Sse2.sub_epi32(s, Sse2.cmpeq_epi32(s, Sse2.setzero_si128())); } - else if (Ssse3.IsSsse3Supported) + else if (constexpr.ALL_EQ_EPI32(a, 1, elements) || constexpr.ALL_EQ_EPI32(a, -1, elements)) { - if (!(promise || constexpr.ALL_NEQ_EPI32(s, 0, elements))) - { - s = Sse2.sub_epi32(s, Sse2.cmpeq_epi32(s, Sse2.setzero_si128())); - } - - return Ssse3.sign_epi32(abs_epi32(a, elements), s); + return Sse2.or_si128(srai_epi32(s, 31), Sse2.set1_epi32(1)); } - else - { - v128 res = Sse2.xor_si128(a, s); - res = Sse2.srai_epi32(res, 31); - return Sse2.sub_epi32(Sse2.xor_si128(a, res), res); + return Ssse3.sign_epi32(abs_epi32(a, elements), s); + } + else if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_EQ_EPI32(a, 1, elements) || constexpr.ALL_EQ_EPI32(a, -1, elements)) + { + return Sse2.or_si128(srai_epi32(s, 31), Sse2.set1_epi32(1)); } + + v128 res = Sse2.xor_si128(a, s); + res = Sse2.srai_epi32(res, 31); + + return Sse2.sub_epi32(Sse2.xor_si128(a, res), res); } else throw new IllegalInstructionException(); } @@ -135,19 +149,16 @@ public static v256 mm256_movsign_epi32(v256 a, v256 s, bool promise = false) { if (Avx2.IsAvx2Supported) { - if (constexpr.ALL_EQ_EPI32(a, 1) || constexpr.ALL_EQ_EPI32(a, -1)) + if (!(promise || constexpr.ALL_NEQ_EPI32(s, 0))) { - return Avx2.mm256_or_si256(Avx.mm256_set1_epi32(1), Avx2.mm256_srai_epi32(s, 31)); + s = Avx2.mm256_sub_epi32(s, Avx2.mm256_cmpeq_epi32(s, Avx.mm256_setzero_si256())); } - else + else if (constexpr.ALL_EQ_EPI32(a, 1) || constexpr.ALL_EQ_EPI32(a, -1)) { - if (!(promise || constexpr.ALL_NEQ_EPI32(s, 0))) - { - s = Avx2.mm256_sub_epi32(s, Avx2.mm256_cmpeq_epi32(s, Avx.mm256_setzero_si256())); - } - - return Avx2.mm256_sign_epi32(mm256_abs_epi32(a), s); + return Avx2.mm256_or_si256(mm256_srai_epi32(s, 31), Avx.mm256_set1_epi32(1)); } + + return Avx2.mm256_sign_epi32(mm256_abs_epi32(a), s); } else throw new IllegalInstructionException(); } @@ -542,7 +553,7 @@ public static int2 copysign(int2 x, int2 y, Promise nonZero = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.movsign_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero), 2)); + return RegisterConversion.ToInt2(Xse.movsign_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero), 2)); } else { @@ -559,7 +570,7 @@ public static int3 copysign(int3 x, int3 y, Promise nonZero = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.movsign_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero), 3)); + return RegisterConversion.ToInt3(Xse.movsign_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero), 3)); } else { @@ -576,7 +587,7 @@ public static int4 copysign(int4 x, int4 y, Promise nonZero = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.movsign_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero), 4)); + return RegisterConversion.ToInt4(Xse.movsign_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero), 4)); } else { @@ -668,7 +679,7 @@ public static quarter copysign(quarter x, quarter y, Promise nonZero = Promise.N { if (Sse2.IsSse2Supported) { - return new quarter(Xse.movsign_pq(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero)).Byte0); + return new quarter(Xse.movsign_pq(RegisterConversion.ToV128(x.value), RegisterConversion.ToV128(y.value), nonZero.Promises(Promise.NonZero)).Byte0); } else { @@ -702,7 +713,7 @@ public static quarter2 copysign(quarter2 x, quarter2 y, Promise nonZero = Promis { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.movsign_pq(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); + return Xse.movsign_pq(x, y, nonZero.Promises(Promise.NonZero)); } else { @@ -717,7 +728,7 @@ public static quarter3 copysign(quarter3 x, quarter3 y, Promise nonZero = Promis { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.movsign_pq(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); + return Xse.movsign_pq(x, y, nonZero.Promises(Promise.NonZero)); } else { @@ -732,7 +743,7 @@ public static quarter4 copysign(quarter4 x, quarter4 y, Promise nonZero = Promis { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.movsign_pq(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); + return Xse.movsign_pq(x, y, nonZero.Promises(Promise.NonZero)); } else { @@ -747,7 +758,7 @@ public static quarter8 copysign(quarter8 x, quarter8 y, Promise nonZero = Promis { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.movsign_pq(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); + return Xse.movsign_pq(x, y, nonZero.Promises(Promise.NonZero)); } else { @@ -797,7 +808,7 @@ public static half2 copysign(half2 x, half2 y, Promise nonZero = Promise.Nothing { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.movsign_ph(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); + return RegisterConversion.ToHalf2(Xse.movsign_ph(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); } else { @@ -812,7 +823,7 @@ public static half3 copysign(half3 x, half3 y, Promise nonZero = Promise.Nothing { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.movsign_ph(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); + return RegisterConversion.ToHalf3(Xse.movsign_ph(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); } else { @@ -827,7 +838,7 @@ public static half4 copysign(half4 x, half4 y, Promise nonZero = Promise.Nothing { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.movsign_ph(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); + return RegisterConversion.ToHalf4(Xse.movsign_ph(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); } else { @@ -842,7 +853,7 @@ public static half8 copysign(half8 x, half8 y, Promise nonZero = Promise.Nothing { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.movsign_ph(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); + return Xse.movsign_ph(x, y, nonZero.Promises(Promise.NonZero)); } else { @@ -892,7 +903,7 @@ public static float2 copysign(float2 x, float2 y, Promise nonZero = Promise.Noth { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.movsign_ps(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); + return RegisterConversion.ToFloat2(Xse.movsign_ps(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); } else { @@ -925,7 +936,7 @@ public static float3 copysign(float3 x, float3 y, Promise nonZero = Promise.Noth { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.movsign_ps(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); + return RegisterConversion.ToFloat3(Xse.movsign_ps(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); } else { @@ -958,7 +969,7 @@ public static float4 copysign(float4 x, float4 y, Promise nonZero = Promise.Noth { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.movsign_ps(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); + return RegisterConversion.ToFloat4(Xse.movsign_ps(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); } else { @@ -1041,7 +1052,7 @@ public static double2 copysign(double2 x, double2 y, Promise nonZero = Promise.N { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.movsign_pd(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); + return RegisterConversion.ToDouble2(Xse.movsign_pd(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), nonZero.Promises(Promise.NonZero))); } else { @@ -1074,7 +1085,7 @@ public static double3 copysign(double3 x, double3 y, Promise nonZero = Promise.N { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Xse.mm256_movsign_pd(RegisterConversion.ToV256(x), RegisterConversion.ToV256(y), nonZero.Promises(Promise.NonZero))); + return RegisterConversion.ToDouble3(Xse.mm256_movsign_pd(RegisterConversion.ToV256(x), RegisterConversion.ToV256(y), nonZero.Promises(Promise.NonZero))); } else { @@ -1090,7 +1101,7 @@ public static double4 copysign(double4 x, double4 y, Promise nonZero = Promise.N { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Xse.mm256_movsign_pd(RegisterConversion.ToV256(x), RegisterConversion.ToV256(y), nonZero.Promises(Promise.NonZero))); + return RegisterConversion.ToDouble4(Xse.mm256_movsign_pd(RegisterConversion.ToV256(x), RegisterConversion.ToV256(y), nonZero.Promises(Promise.NonZero))); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Sign/Negative-Absolute.cs b/Runtime/Math Lib/Functions/Arithmetic/Sign/Negative-Absolute.cs index d310208..c4bef9b 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Sign/Negative-Absolute.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Sign/Negative-Absolute.cs @@ -407,7 +407,7 @@ public static int2 nabs(int2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.nabs_epi32(RegisterConversion.ToV128(x), 2)); + return RegisterConversion.ToInt2(Xse.nabs_epi32(RegisterConversion.ToV128(x), 2)); } else { @@ -421,7 +421,7 @@ public static int3 nabs(int3 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.nabs_epi32(RegisterConversion.ToV128(x), 3)); + return RegisterConversion.ToInt3(Xse.nabs_epi32(RegisterConversion.ToV128(x), 3)); } else { @@ -435,7 +435,7 @@ public static int4 nabs(int4 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.nabs_epi32(RegisterConversion.ToV128(x), 4)); + return RegisterConversion.ToInt4(Xse.nabs_epi32(RegisterConversion.ToV128(x), 4)); } else { @@ -670,7 +670,7 @@ public static float2 nabs(float2 x) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Xse.nabs_ps(RegisterConversion.ToV128(x), 2)); + return RegisterConversion.ToFloat2(Xse.nabs_ps(RegisterConversion.ToV128(x), 2)); } else { @@ -684,7 +684,7 @@ public static float3 nabs(float3 x) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Xse.nabs_ps(RegisterConversion.ToV128(x), 3)); + return RegisterConversion.ToFloat3(Xse.nabs_ps(RegisterConversion.ToV128(x), 3)); } else { @@ -698,7 +698,7 @@ public static float4 nabs(float4 x) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Xse.nabs_ps(RegisterConversion.ToV128(x), 4)); + return RegisterConversion.ToFloat4(Xse.nabs_ps(RegisterConversion.ToV128(x), 4)); } else { @@ -741,7 +741,7 @@ public static double2 nabs(double2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.nabs_pd(RegisterConversion.ToV128(x))); + return RegisterConversion.ToDouble2(Xse.nabs_pd(RegisterConversion.ToV128(x))); } else { @@ -755,7 +755,7 @@ public static double3 nabs(double3 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType( Xse.mm256_nabs_pd(RegisterConversion.ToV256(x), 3)); + return RegisterConversion.ToDouble3( Xse.mm256_nabs_pd(RegisterConversion.ToV256(x), 3)); } else { @@ -769,7 +769,7 @@ public static double4 nabs(double4 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.mm256_nabs_pd(RegisterConversion.ToV256(x), 4)); + return RegisterConversion.ToDouble4(Xse.mm256_nabs_pd(RegisterConversion.ToV256(x), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Sign/Sign.cs b/Runtime/Math Lib/Functions/Arithmetic/Sign/Sign.cs index 5d3bd78..ca6cecf 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Sign/Sign.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Sign/Sign.cs @@ -249,7 +249,7 @@ public static int2 sign(int2 x) { if (Ssse3.IsSsse3Supported) { - return RegisterConversion.ToType(Ssse3.sign_epi32(new v128(1, 1, 0, 0), RegisterConversion.ToV128(x))); + return RegisterConversion.ToInt2(Ssse3.sign_epi32(new v128(1, 1, 0, 0), RegisterConversion.ToV128(x))); } else { @@ -263,7 +263,7 @@ public static int3 sign(int3 x) { if (Ssse3.IsSsse3Supported) { - return RegisterConversion.ToType(Ssse3.sign_epi32(new v128(1, 1, 1, 0), RegisterConversion.ToV128(x))); + return RegisterConversion.ToInt3(Ssse3.sign_epi32(new v128(1, 1, 1, 0), RegisterConversion.ToV128(x))); } else { @@ -277,7 +277,7 @@ public static int4 sign(int4 x) { if (Ssse3.IsSsse3Supported) { - return RegisterConversion.ToType(Ssse3.sign_epi32(new v128(1), RegisterConversion.ToV128(x))); + return RegisterConversion.ToInt4(Ssse3.sign_epi32(new v128(1), RegisterConversion.ToV128(x))); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Subtract-Add.cs b/Runtime/Math Lib/Functions/Arithmetic/Subtract-Add.cs index 1bd2d4d..3a28287 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Subtract-Add.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Subtract-Add.cs @@ -243,7 +243,7 @@ public static float2 subadd(float2 a, float2 b) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Xse.addsub_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); + return RegisterConversion.ToFloat2(Xse.addsub_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); } else { @@ -257,7 +257,7 @@ public static float3 subadd(float3 a, float3 b) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Xse.addsub_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); + return RegisterConversion.ToFloat3(Xse.addsub_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); } else { @@ -271,7 +271,7 @@ public static float4 subadd(float4 a, float4 b) { if (Sse.IsSseSupported) { - return RegisterConversion.ToType(Xse.addsub_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); + return RegisterConversion.ToFloat4(Xse.addsub_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); } else { @@ -300,7 +300,7 @@ public static double2 subadd(double2 a, double2 b) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.addsub_pd(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b)));; + return RegisterConversion.ToDouble2(Xse.addsub_pd(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b)));; } else { @@ -314,7 +314,7 @@ public static double3 subadd(double3 a, double3 b) { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Avx.mm256_addsub_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b))); + return RegisterConversion.ToDouble3(Avx.mm256_addsub_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b))); } else { @@ -328,7 +328,7 @@ public static double4 subadd(double4 a, double4 b) { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Avx.mm256_addsub_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b))); + return RegisterConversion.ToDouble4(Avx.mm256_addsub_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b))); } else { @@ -578,7 +578,7 @@ public static uint2 subadd(uint2 a, uint2 b) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.addsub_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 2)); + return RegisterConversion.ToUInt2(Xse.addsub_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 2)); } else { @@ -592,7 +592,7 @@ public static uint3 subadd(uint3 a, uint3 b) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.addsub_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 3)); + return RegisterConversion.ToUInt3(Xse.addsub_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 3)); } else { @@ -606,7 +606,7 @@ public static uint4 subadd(uint4 a, uint4 b) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.addsub_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 4)); + return RegisterConversion.ToUInt4(Xse.addsub_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Vector Reduction/Column Average.cs b/Runtime/Math Lib/Functions/Arithmetic/Vector Reduction/Column Average.cs index 66d1fb5..f1dac4c 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Vector Reduction/Column Average.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Vector Reduction/Column Average.cs @@ -1,6 +1,5 @@ using System.Runtime.CompilerServices; using Unity.Mathematics; -using Unity.Burst.CompilerServices; using Unity.Burst.Intrinsics; using MaxMath.Intrinsics; @@ -87,7 +86,7 @@ public static v128 vavg_epi8(v128 a, bool promiseNoOverflow = false, byte elemen } v128 offset = Sse2.cvtsi32_si128(elements - 1); - v128 csum = Xse.vsum_epi8(a, promiseNoOverflow, elements); + v128 csum = vsum_epi8(a, promiseNoOverflow, elements); v128 result; if (promiseNoOverflow) @@ -98,11 +97,12 @@ public static v128 vavg_epi8(v128 a, bool promiseNoOverflow = false, byte elemen } else { - offset = movsign_epi8(offset, csum, false, 1); + v128 signMaskSum = srai_epi8(csum, 7); + offset = Sse2.sub_epi8(Sse2.xor_si128(offset, signMaskSum), signMaskSum); } result = Sse2.add_epi8(csum, offset); - result = Xse.constexpr.div_epi8(result, (sbyte)elements, elements); + result = constexpr.div_epi8(result, (sbyte)elements, elements); } else { @@ -112,11 +112,12 @@ public static v128 vavg_epi8(v128 a, bool promiseNoOverflow = false, byte elemen } else { - offset = movsign_epi16(offset, csum, false, 1); + v128 signMaskSum = Sse2.srai_epi16(csum, 15); + offset = Sse2.sub_epi16(Sse2.xor_si128(offset, signMaskSum), signMaskSum); } result = Sse2.add_epi16(csum, offset); - result = Xse.constexpr.div_epi16(result, elements, elements); + result = constexpr.div_epi16(result, elements, elements); } return result; @@ -139,7 +140,7 @@ public static v128 vavg_epi16(v128 a, bool promiseNoOverflow = false, byte eleme } v128 offset = Sse2.cvtsi32_si128(elements - 1); - v128 csum = Xse.vsum_epi16(a, promiseNoOverflow, elements); + v128 csum = vsum_epi16(a, promiseNoOverflow, elements); v128 result; if (promiseNoOverflow) @@ -150,11 +151,12 @@ public static v128 vavg_epi16(v128 a, bool promiseNoOverflow = false, byte eleme } else { - offset = movsign_epi16(offset, csum, false, 1); + v128 signMaskSum = Sse2.srai_epi16(csum, 15); + offset = Sse2.sub_epi16(Sse2.xor_si128(offset, signMaskSum), signMaskSum); } result = Sse2.add_epi16(csum, offset); - result = Xse.constexpr.div_epi16(result, elements, elements); + result = constexpr.div_epi16(result, elements, elements); } else { @@ -164,11 +166,12 @@ public static v128 vavg_epi16(v128 a, bool promiseNoOverflow = false, byte eleme } else { - offset = movsign_epi32(offset, csum, false, 1); + v128 signMaskSum = Sse2.srai_epi32(csum, 31); + offset = Sse2.sub_epi32(Sse2.xor_si128(offset, signMaskSum), signMaskSum); } result = Sse2.add_epi32(csum, offset); - result = Xse.constexpr.div_epi32(result, elements); + result = constexpr.div_epi32(result, elements); } return result; @@ -191,7 +194,7 @@ public static v128 vavg_epi32(v128 a, bool promiseNoOverflow = false, byte eleme } v128 offset = Sse2.cvtsi32_si128(elements - 1); - v128 csum = Xse.vsum_epi32(a, promiseNoOverflow, elements); + v128 csum = vsum_epi32(a, promiseNoOverflow, elements); v128 result; if (promiseNoOverflow) @@ -202,18 +205,20 @@ public static v128 vavg_epi32(v128 a, bool promiseNoOverflow = false, byte eleme } else { - offset = movsign_epi32(offset, csum, false, 1); + v128 signMaskSum = Sse2.srai_epi32(csum, 31); + offset = Sse2.sub_epi32(Sse2.xor_si128(offset, signMaskSum), signMaskSum); } result = Sse2.add_epi32(csum, offset); - result = Xse.constexpr.div_epi32(result, elements); + result = constexpr.div_epi32(result, elements); } else { - offset = movsign_epi64(offset, csum); + v128 signMaskSum = srai_epi64(csum, 63); + offset = Sse2.sub_epi64(Sse2.xor_si128(offset, signMaskSum), signMaskSum); result = Sse2.add_epi64(csum, offset); - result = Xse.constexpr.div_epi64(result, elements); + result = constexpr.div_epi64(result, elements); } return result; @@ -329,7 +334,7 @@ public static byte cavg(byte32 c) /// Returns the ceiling of the horizontal average value of components in an . - /// A withs its flag set returns undefined results for any column sum of or 1 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 1 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 1 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 1 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte cavg(sbyte2 c, Promise noOverflow = Promise.Nothing) { @@ -344,7 +349,7 @@ public static sbyte cavg(sbyte2 c, Promise noOverflow = Promise.Nothing) } /// Returns the ceiling of the horizontal average value of components in an . - /// A withs its flag set returns undefined results for any column sum of or 2 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 2 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 2 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 2 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte cavg(sbyte3 c, Promise noOverflow = Promise.Nothing) { @@ -361,7 +366,7 @@ public static sbyte cavg(sbyte3 c, Promise noOverflow = Promise.Nothing) } /// Returns the ceiling of the horizontal average value of components in an . - /// A withs its flag set returns undefined results for any column sum of or 3 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 3 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 3 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 3 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte cavg(sbyte4 c, Promise noOverflow = Promise.Nothing) { @@ -378,7 +383,7 @@ public static sbyte cavg(sbyte4 c, Promise noOverflow = Promise.Nothing) } /// Returns the ceiling of the horizontal average value of components in an . - /// A withs its flag set returns undefined results for any column sum of or 7 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 7 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 7 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 7 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte cavg(sbyte8 c, Promise noOverflow = Promise.Nothing) { @@ -395,7 +400,7 @@ public static sbyte cavg(sbyte8 c, Promise noOverflow = Promise.Nothing) } /// Returns the ceiling of the horizontal average value of components in an . - /// A withs its flag set returns undefined results for any column sum of or 15 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 15 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 15 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 15 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte cavg(sbyte16 c, Promise noOverflow = Promise.Nothing) { @@ -412,7 +417,7 @@ public static sbyte cavg(sbyte16 c, Promise noOverflow = Promise.Nothing) } /// Returns the ceiling of the horizontal average value of components in an . - /// A withs its flag set returns undefined results for any column sum of or 31 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 31 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 31 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 31 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte cavg(sbyte32 c, Promise noOverflow = Promise.Nothing) { @@ -589,7 +594,7 @@ public static ushort cavg(ushort16 c, Promise noOverflow = Promise.Nothing) /// Returns the ceiling of the horizontal average value of components in a . - /// A withs its flag set returns undefined results for any column sum of or 1 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 1 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 1 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 1 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short cavg(short2 c, Promise noOverflow = Promise.Nothing) { @@ -604,7 +609,7 @@ public static short cavg(short2 c, Promise noOverflow = Promise.Nothing) } /// Returns the ceiling of the horizontal average value of components in a . - /// A withs its flag set returns undefined results for any column sum of or 2 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 2 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 2 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 2 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short cavg(short3 c, Promise noOverflow = Promise.Nothing) { @@ -621,7 +626,7 @@ public static short cavg(short3 c, Promise noOverflow = Promise.Nothing) } /// Returns the ceiling of the horizontal average value of components in a . - /// A withs its flag set returns undefined results for any column sum of or 3 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 3 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 3 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 3 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short cavg(short4 c, Promise noOverflow = Promise.Nothing) { @@ -638,7 +643,7 @@ public static short cavg(short4 c, Promise noOverflow = Promise.Nothing) } /// Returns the ceiling of the horizontal average value of components in a . - /// A withs its flag set returns undefined results for any column sum of or 7 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 7 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 7 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 7 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short cavg(short8 c, Promise noOverflow = Promise.Nothing) { @@ -655,7 +660,7 @@ public static short cavg(short8 c, Promise noOverflow = Promise.Nothing) } /// Returns the ceiling of the horizontal average value of components in a . - /// A withs its flag set returns undefined results for any column sum of or 15 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 15 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 15 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 15 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short cavg(short16 c, Promise noOverflow = Promise.Nothing) { @@ -753,7 +758,7 @@ public static uint cavg(uint3 c, Promise noOverflow = Promise.Nothing) } else { - return (uint)((2 + (ulong)c.z + csum((ulong2)c.xy)) / 3); + return (uint)(((2 + (ulong)c.z) + csum((ulong2)c.xy)) / 3); } } @@ -828,7 +833,7 @@ public static uint cavg(uint8 c, Promise noOverflow = Promise.Nothing) /// Returns the ceiling of the horizontal average value of components in an . - /// A withs its flag set returns undefined results for any column sum of or 1 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 1 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 1 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 1 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int cavg(int2 c, Promise noOverflow = Promise.Nothing) { @@ -843,7 +848,7 @@ public static int cavg(int2 c, Promise noOverflow = Promise.Nothing) } /// Returns the ceiling of the horizontal average value of components in an . - /// A withs its flag set returns undefined results for any column sum of or 2 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 2 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 2 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 2 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int cavg(int3 c, Promise noOverflow = Promise.Nothing) { @@ -860,7 +865,7 @@ public static int cavg(int3 c, Promise noOverflow = Promise.Nothing) } /// Returns the ceiling of the horizontal average value of components in an . - /// A withs its flag set returns undefined results for any column sum of or 3 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 3 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 3 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 3 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int cavg(int4 c, Promise noOverflow = Promise.Nothing) { @@ -877,7 +882,7 @@ public static int cavg(int4 c, Promise noOverflow = Promise.Nothing) } /// Returns the ceiling of the horizontal average value of components in an . - /// A withs its flag set returns undefined results for any column sum of or 7 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 7 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 7 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 7 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int cavg(int8 c, Promise noOverflow = Promise.Nothing) { @@ -1012,7 +1017,7 @@ public static ulong cavg(ulong4 c, Promise noOverflow = Promise.Nothing) /// Returns the ceiling of the horizontal average value of components in a . - /// A withs its flag set returns undefined results for any column sum of or 1 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 1 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 1 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 1 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long cavg(long2 c, Promise noOverflow = Promise.Nothing) { @@ -1029,7 +1034,7 @@ public static long cavg(long2 c, Promise noOverflow = Promise.Nothing) } /// Returns the ceiling of the horizontal average value of components in a . - /// A withs its flag set returns undefined results for any column sum of or 2 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 2 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 2 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 2 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long cavg(long3 c, Promise noOverflow = Promise.Nothing) { @@ -1050,7 +1055,7 @@ public static long cavg(long3 c, Promise noOverflow = Promise.Nothing) } /// Returns the ceiling of the horizontal average value of components in a . - /// A withs its flag set returns undefined results for any column sum of or 3 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 3 is guaranteed not to overflow. + /// A withs its flag set returns undefined results for any column sum of or 3 ('+' if the column sum is positive, '-' otherwise) that overflows. It is only recommended to use this overload if each possible summation order of elements in or 3 is guaranteed not to overflow. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long cavg(long4 c, Promise noOverflow = Promise.Nothing) { diff --git a/Runtime/Math Lib/Functions/Arithmetic/Vector Reduction/Dot Product.cs b/Runtime/Math Lib/Functions/Arithmetic/Vector Reduction/Dot Product.cs index 5485bdc..99025ca 100644 --- a/Runtime/Math Lib/Functions/Arithmetic/Vector Reduction/Dot Product.cs +++ b/Runtime/Math Lib/Functions/Arithmetic/Vector Reduction/Dot Product.cs @@ -9,7 +9,7 @@ namespace MaxMath { namespace Intrinsics - { + { unsafe public static partial class Xse { // maddubs(byte16 a, sbyte16 b) is almost useless. @@ -324,11 +324,11 @@ public static v128 dp_epi16(v128 a, v128 b, bool promiseNoOverflow = false, byte { if (Constant.IsConstantExpression(a)) { - a = Sse2.insert_epi16(a, 0, 3); + a = Xse.insert_epi16(a, 0, 3); } else { - b = Sse2.insert_epi16(b, 0, 3); + b = Xse.insert_epi16(b, 0, 3); } } diff --git a/Runtime/Math Lib/Functions/Bitwise/BMI/Extract Bitfield.cs b/Runtime/Math Lib/Functions/Bitwise/BMI/Extract Bitfield.cs index d49b892..68a71f2 100644 --- a/Runtime/Math Lib/Functions/Bitwise/BMI/Extract Bitfield.cs +++ b/Runtime/Math Lib/Functions/Bitwise/BMI/Extract Bitfield.cs @@ -135,7 +135,7 @@ public static byte bits_extract(byte x, int index, int length) return (byte)bits_extract((uint)x, index, length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte2 bits_extract(byte2 x, byte2 index, byte2 length) { @@ -149,7 +149,7 @@ public static byte2 bits_extract(byte2 x, byte2 index, byte2 length) } } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte3 bits_extract(byte3 x, byte3 index, byte3 length) { @@ -163,7 +163,7 @@ public static byte3 bits_extract(byte3 x, byte3 index, byte3 length) } } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte4 bits_extract(byte4 x, byte4 index, byte4 length) { @@ -177,7 +177,7 @@ public static byte4 bits_extract(byte4 x, byte4 index, byte4 length) } } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte8 bits_extract(byte8 x, byte8 index, byte8 length) { @@ -191,7 +191,7 @@ public static byte8 bits_extract(byte8 x, byte8 index, byte8 length) } } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte16 bits_extract(byte16 x, byte16 index, byte16 length) { @@ -205,7 +205,7 @@ public static byte16 bits_extract(byte16 x, byte16 index, byte16 length) } } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte32 bits_extract(byte32 x, byte32 index, byte32 length) { @@ -227,42 +227,42 @@ public static sbyte bits_extract(sbyte x, int index, int length) return (sbyte)bits_extract((byte)x, index, length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte2 bits_extract(sbyte2 x, sbyte2 index, sbyte2 length) { return (sbyte2)bits_extract((byte2)x, (byte2)index, (byte2)length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte3 bits_extract(sbyte3 x, sbyte3 index, sbyte3 length) { return (sbyte3)bits_extract((byte3)x, (byte3)index, (byte3)length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte4 bits_extract(sbyte4 x, sbyte4 index, sbyte4 length) { return (sbyte4)bits_extract((byte4)x, (byte4)index, (byte4)length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte8 bits_extract(sbyte8 x, sbyte8 index, sbyte8 length) { return (sbyte8)bits_extract((byte8)x, (byte8)index, (byte8)length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte16 bits_extract(sbyte16 x, sbyte16 index, sbyte16 length) { return (sbyte16)bits_extract((byte16)x, (byte16)index, (byte16)length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte32 bits_extract(sbyte32 x, sbyte32 index, sbyte32 length) { @@ -277,7 +277,7 @@ public static ushort bits_extract(ushort x, int index, int length) return (ushort)bits_extract((uint)x, index, length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort2 bits_extract(ushort2 x, ushort2 index, ushort2 length) { @@ -291,7 +291,7 @@ public static ushort2 bits_extract(ushort2 x, ushort2 index, ushort2 length) } } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort3 bits_extract(ushort3 x, ushort3 index, ushort3 length) { @@ -305,7 +305,7 @@ public static ushort3 bits_extract(ushort3 x, ushort3 index, ushort3 length) } } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort4 bits_extract(ushort4 x, ushort4 index, ushort4 length) { @@ -319,7 +319,7 @@ public static ushort4 bits_extract(ushort4 x, ushort4 index, ushort4 length) } } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort8 bits_extract(ushort8 x, ushort8 index, ushort8 length) { @@ -333,7 +333,7 @@ public static ushort8 bits_extract(ushort8 x, ushort8 index, ushort8 length) } } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort16 bits_extract(ushort16 x, ushort16 index, ushort16 length) { @@ -355,35 +355,35 @@ public static short bits_extract(short x, int index, int length) return (short)bits_extract((ushort)x, index, length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short2 bits_extract(short2 x, short2 index, short2 length) { return (short2)bits_extract((ushort2)x, (ushort2)index, (ushort2)length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short3 bits_extract(short3 x, short3 index, short3 length) { return (short3)bits_extract((ushort3)x, (ushort3)index, (ushort3)length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short4 bits_extract(short4 x, short4 index, short4 length) { return (short4)bits_extract((ushort4)x, (ushort4)index, (ushort4)length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short8 bits_extract(short8 x, short8 index, short8 length) { return (short8)bits_extract((ushort8)x, (ushort8)index, (ushort8)length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short16 bits_extract(short16 x, short16 index, short16 length) { @@ -405,13 +405,13 @@ public static uint bits_extract(uint x, int index, int length) } } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint2 bits_extract(uint2 x, uint2 index, uint2 length) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.bextr_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(index), RegisterConversion.ToV128(length), 2)); + return RegisterConversion.ToUInt2(Xse.bextr_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(index), RegisterConversion.ToV128(length), 2)); } else { @@ -419,13 +419,13 @@ public static uint2 bits_extract(uint2 x, uint2 index, uint2 length) } } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint3 bits_extract(uint3 x, uint3 index, uint3 length) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.bextr_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(index), RegisterConversion.ToV128(length), 3)); + return RegisterConversion.ToUInt3(Xse.bextr_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(index), RegisterConversion.ToV128(length), 3)); } else { @@ -433,13 +433,13 @@ public static uint3 bits_extract(uint3 x, uint3 index, uint3 length) } } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint4 bits_extract(uint4 x, uint4 index, uint4 length) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.bextr_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(index), RegisterConversion.ToV128(length), 4)); + return RegisterConversion.ToUInt4(Xse.bextr_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(index), RegisterConversion.ToV128(length), 4)); } else { @@ -447,7 +447,7 @@ public static uint4 bits_extract(uint4 x, uint4 index, uint4 length) } } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint8 bits_extract(uint8 x, uint8 index, uint8 length) { @@ -469,28 +469,28 @@ public static int bits_extract(int x, int index, int length) return (int)bits_extract((uint)x, index, length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int2 bits_extract(int2 x, int2 index, int2 length) { return (int2)bits_extract((uint2)x, (uint2)index, (uint2)length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int3 bits_extract(int3 x, int3 index, int3 length) { return (int3)bits_extract((uint3)x, (uint3)index, (uint3)length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int4 bits_extract(int4 x, int4 index, int4 length) { return (int4)bits_extract((uint4)x, (uint4)index, (uint4)length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of an and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int8 bits_extract(int8 x, int8 index, int8 length) { @@ -512,7 +512,7 @@ public static ulong bits_extract(ulong x, int index, int length) } } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong2 bits_extract(ulong2 x, ulong2 index, ulong2 length) { @@ -526,7 +526,7 @@ public static ulong2 bits_extract(ulong2 x, ulong2 index, ulong2 length) } } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong3 bits_extract(ulong3 x, ulong3 index, ulong3 length) { @@ -540,7 +540,7 @@ public static ulong3 bits_extract(ulong3 x, ulong3 index, ulong3 length) } } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong4 bits_extract(ulong4 x, ulong4 index, ulong4 length) { @@ -562,21 +562,21 @@ public static long bits_extract(long x, int index, int length) return (long)bits_extract((ulong)x, index, length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long2 bits_extract(long2 x, long2 index, long2 length) { return (long2)bits_extract((ulong2)x, (ulong2)index, (ulong2)length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long3 bits_extract(long3 x, long3 index, long3 length) { return (long3)bits_extract((ulong3)x, (ulong3)index, (ulong3)length); } - /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit int that component to 0. + /// Shifts a bitfield in each component of the corresponding length and starting at the corresponding bit to the least significant bit of a and sets each remaining bit in that component to 0. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long4 bits_extract(long4 x, long4 index, long4 length) { diff --git a/Runtime/Math Lib/Functions/Bitwise/BMI/Extract Lowest Set Bit.cs b/Runtime/Math Lib/Functions/Bitwise/BMI/Extract Lowest Set Bit.cs index f3bb0de..3e2ad90 100644 --- a/Runtime/Math Lib/Functions/Bitwise/BMI/Extract Lowest Set Bit.cs +++ b/Runtime/Math Lib/Functions/Bitwise/BMI/Extract Lowest Set Bit.cs @@ -411,7 +411,7 @@ public static uint2 bits_extractlowest(uint2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.blsi_epi32(RegisterConversion.ToV128(x))); + return RegisterConversion.ToUInt2(Xse.blsi_epi32(RegisterConversion.ToV128(x))); } else { @@ -425,7 +425,7 @@ public static uint3 bits_extractlowest(uint3 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.blsi_epi32(RegisterConversion.ToV128(x))); + return RegisterConversion.ToUInt3(Xse.blsi_epi32(RegisterConversion.ToV128(x))); } else { @@ -439,7 +439,7 @@ public static uint4 bits_extractlowest(uint4 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.blsi_epi32(RegisterConversion.ToV128(x))); + return RegisterConversion.ToUInt4(Xse.blsi_epi32(RegisterConversion.ToV128(x))); } else { diff --git a/Runtime/Math Lib/Functions/Bitwise/BMI/Mask Up To Lowest Set Bit.cs b/Runtime/Math Lib/Functions/Bitwise/BMI/Mask Up To Lowest Set Bit.cs index 4aa75e7..192f562 100644 --- a/Runtime/Math Lib/Functions/Bitwise/BMI/Mask Up To Lowest Set Bit.cs +++ b/Runtime/Math Lib/Functions/Bitwise/BMI/Mask Up To Lowest Set Bit.cs @@ -395,7 +395,7 @@ public static uint2 bits_masktolowest(uint2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.blsmsk_epi32(RegisterConversion.ToV128(x))); + return RegisterConversion.ToUInt2(Xse.blsmsk_epi32(RegisterConversion.ToV128(x))); } else { @@ -409,7 +409,7 @@ public static uint3 bits_masktolowest(uint3 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.blsmsk_epi32(RegisterConversion.ToV128(x))); + return RegisterConversion.ToUInt3(Xse.blsmsk_epi32(RegisterConversion.ToV128(x))); } else { @@ -423,7 +423,7 @@ public static uint4 bits_masktolowest(uint4 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.blsmsk_epi32(RegisterConversion.ToV128(x))); + return RegisterConversion.ToUInt4(Xse.blsmsk_epi32(RegisterConversion.ToV128(x))); } else { diff --git a/Runtime/Math Lib/Functions/Bitwise/BMI/Parallel Bit Deposit.cs b/Runtime/Math Lib/Functions/Bitwise/BMI/Parallel Bit Deposit.cs index f471396..cd3dccd 100644 --- a/Runtime/Math Lib/Functions/Bitwise/BMI/Parallel Bit Deposit.cs +++ b/Runtime/Math Lib/Functions/Bitwise/BMI/Parallel Bit Deposit.cs @@ -523,7 +523,7 @@ public static uint2 bits_depositparallel(uint2 x, uint2 mask) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.pdep_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(mask), 2)); + return RegisterConversion.ToUInt2(Xse.pdep_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(mask), 2)); } else { @@ -537,7 +537,7 @@ public static uint3 bits_depositparallel(uint3 x, uint3 mask) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.pdep_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(mask), 3)); + return RegisterConversion.ToUInt3(Xse.pdep_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(mask), 3)); } else { @@ -551,7 +551,7 @@ public static uint4 bits_depositparallel(uint4 x, uint4 mask) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.pdep_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(mask), 4)); + return RegisterConversion.ToUInt4(Xse.pdep_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(mask), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Bitwise/BMI/Parallel Bit Extract.cs b/Runtime/Math Lib/Functions/Bitwise/BMI/Parallel Bit Extract.cs index 2ed40f1..f2e8e2d 100644 --- a/Runtime/Math Lib/Functions/Bitwise/BMI/Parallel Bit Extract.cs +++ b/Runtime/Math Lib/Functions/Bitwise/BMI/Parallel Bit Extract.cs @@ -536,7 +536,7 @@ public static uint2 bits_extractparallel(uint2 x, uint2 mask) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.pext_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(mask), 2)); + return RegisterConversion.ToUInt2(Xse.pext_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(mask), 2)); } else { @@ -550,7 +550,7 @@ public static uint3 bits_extractparallel(uint3 x, uint3 mask) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.pext_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(mask), 3)); + return RegisterConversion.ToUInt3(Xse.pext_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(mask), 3)); } else { @@ -564,7 +564,7 @@ public static uint4 bits_extractparallel(uint4 x, uint4 mask) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.pext_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(mask), 4)); + return RegisterConversion.ToUInt4(Xse.pext_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(mask), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Bitwise/BMI/Reset Lowest Set Bit.cs b/Runtime/Math Lib/Functions/Bitwise/BMI/Reset Lowest Set Bit.cs index bf5d2d5..697d3c9 100644 --- a/Runtime/Math Lib/Functions/Bitwise/BMI/Reset Lowest Set Bit.cs +++ b/Runtime/Math Lib/Functions/Bitwise/BMI/Reset Lowest Set Bit.cs @@ -395,7 +395,7 @@ public static uint2 bits_resetlowest(uint2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.blsr_epi32(RegisterConversion.ToV128(x))); + return RegisterConversion.ToUInt2(Xse.blsr_epi32(RegisterConversion.ToV128(x))); } else { @@ -409,7 +409,7 @@ public static uint3 bits_resetlowest(uint3 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.blsr_epi32(RegisterConversion.ToV128(x))); + return RegisterConversion.ToUInt3(Xse.blsr_epi32(RegisterConversion.ToV128(x))); } else { @@ -423,7 +423,7 @@ public static uint4 bits_resetlowest(uint4 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.blsr_epi32(RegisterConversion.ToV128(x))); + return RegisterConversion.ToUInt4(Xse.blsr_epi32(RegisterConversion.ToV128(x))); } else { diff --git a/Runtime/Math Lib/Functions/Bitwise/BMI/Zero High Bits.cs b/Runtime/Math Lib/Functions/Bitwise/BMI/Zero High Bits.cs index b129801..2152465 100644 --- a/Runtime/Math Lib/Functions/Bitwise/BMI/Zero High Bits.cs +++ b/Runtime/Math Lib/Functions/Bitwise/BMI/Zero High Bits.cs @@ -460,7 +460,7 @@ public static uint2 bits_zerohigh(uint2 x, uint2 startIndex) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.bzhi_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(startIndex), 2)); + return RegisterConversion.ToUInt2(Xse.bzhi_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(startIndex), 2)); } else { @@ -474,7 +474,7 @@ public static uint3 bits_zerohigh(uint3 x, uint3 startIndex) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.bzhi_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(startIndex), 3)); + return RegisterConversion.ToUInt3(Xse.bzhi_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(startIndex), 3)); } else { @@ -488,7 +488,7 @@ public static uint4 bits_zerohigh(uint4 x, uint4 startIndex) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.bzhi_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(startIndex), 4)); + return RegisterConversion.ToUInt4(Xse.bzhi_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(startIndex), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Bitwise/Bit Fields/Bit Field.cs b/Runtime/Math Lib/Functions/Bitwise/Bit Fields/Bit Field.cs index ecceb1e..ffeeeae 100644 --- a/Runtime/Math Lib/Functions/Bitwise/Bit Fields/Bit Field.cs +++ b/Runtime/Math Lib/Functions/Bitwise/Bit Fields/Bit Field.cs @@ -212,7 +212,7 @@ public static uint2 bitfield(byte2 x0, byte2 x1, byte2 x2, byte2 x3) v128 lo0 = Sse2.unpacklo_epi8(x0, x1); v128 lo1 = Sse2.unpacklo_epi8(x2, x3); - return RegisterConversion.ToType(Sse2.unpacklo_epi16(lo0, lo1)); + return RegisterConversion.ToUInt2(Sse2.unpacklo_epi16(lo0, lo1)); } else { @@ -229,7 +229,7 @@ public static uint3 bitfield(byte3 x0, byte3 x1, byte3 x2, byte3 x3) v128 lo0 = Sse2.unpacklo_epi8(x0, x1); v128 lo1 = Sse2.unpacklo_epi8(x2, x3); - return RegisterConversion.ToType(Sse2.unpacklo_epi16(lo0, lo1)); + return RegisterConversion.ToUInt3(Sse2.unpacklo_epi16(lo0, lo1)); } else { @@ -246,7 +246,7 @@ public static uint4 bitfield(byte4 x0, byte4 x1, byte4 x2, byte4 x3) v128 lo0 = Sse2.unpacklo_epi8(x0, x1); v128 lo1 = Sse2.unpacklo_epi8(x2, x3); - return RegisterConversion.ToType(Sse2.unpacklo_epi16(lo0, lo1)); + return RegisterConversion.ToUInt4(Sse2.unpacklo_epi16(lo0, lo1)); } else { @@ -271,7 +271,7 @@ public static uint8 bitfield(byte8 x0, byte8 x1, byte8 x2, byte8 x3) } else { - return new uint8(RegisterConversion.ToType(resultlo), RegisterConversion.ToType(resulthi)); + return new uint8(RegisterConversion.ToUInt4(resultlo), RegisterConversion.ToUInt4(resulthi)); } } else @@ -337,7 +337,7 @@ public static uint2 bitfield(ushort2 x0, ushort2 x1) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Sse2.unpacklo_epi16(x0, x1)); + return RegisterConversion.ToUInt2(Sse2.unpacklo_epi16(x0, x1)); } else { @@ -351,7 +351,7 @@ public static uint3 bitfield(ushort3 x0, ushort3 x1) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Sse2.unpacklo_epi16(x0, x1)); + return RegisterConversion.ToUInt3(Sse2.unpacklo_epi16(x0, x1)); } else { @@ -365,7 +365,7 @@ public static uint4 bitfield(ushort4 x0, ushort4 x1) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Sse2.unpacklo_epi16(x0, x1)); + return RegisterConversion.ToUInt4(Sse2.unpacklo_epi16(x0, x1)); } else { @@ -388,7 +388,7 @@ public static uint8 bitfield(ushort8 x0, ushort8 x1) } else { - return new uint8(RegisterConversion.ToType(resultlo), RegisterConversion.ToType(resulthi)); + return new uint8(RegisterConversion.ToUInt4(resultlo), RegisterConversion.ToUInt4(resulthi)); } } else diff --git a/Runtime/Math Lib/Functions/Bitwise/Bit Fields/Bitmask.cs b/Runtime/Math Lib/Functions/Bitwise/Bit Fields/Bitmask.cs index 32b7e4d..2cdad3c 100644 --- a/Runtime/Math Lib/Functions/Bitwise/Bit Fields/Bitmask.cs +++ b/Runtime/Math Lib/Functions/Bitwise/Bit Fields/Bitmask.cs @@ -614,7 +614,7 @@ public static uint bitmask32(uint numBits, uint index = 0) if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.bitmask_epi32(RegisterConversion.ToV128(numBits), RegisterConversion.ToV128(index), 2)); + return RegisterConversion.ToUInt2(Xse.bitmask_epi32(RegisterConversion.ToV128(numBits), RegisterConversion.ToV128(index), 2)); } else { @@ -636,7 +636,7 @@ public static uint bitmask32(uint numBits, uint index = 0) if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.bitmask_epi32(RegisterConversion.ToV128(numBits), RegisterConversion.ToV128(index), 3)); + return RegisterConversion.ToUInt3(Xse.bitmask_epi32(RegisterConversion.ToV128(numBits), RegisterConversion.ToV128(index), 3)); } else { @@ -661,7 +661,7 @@ public static uint bitmask32(uint numBits, uint index = 0) if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.bitmask_epi32(RegisterConversion.ToV128(numBits), RegisterConversion.ToV128(index), 4)); + return RegisterConversion.ToUInt4(Xse.bitmask_epi32(RegisterConversion.ToV128(numBits), RegisterConversion.ToV128(index), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Bitwise/Bit Fields/Mask to Boolean Vector.cs b/Runtime/Math Lib/Functions/Bitwise/Bit Fields/Mask to Boolean Vector.cs index 33bd219..d4ff002 100644 --- a/Runtime/Math Lib/Functions/Bitwise/Bit Fields/Mask to Boolean Vector.cs +++ b/Runtime/Math Lib/Functions/Bitwise/Bit Fields/Mask to Boolean Vector.cs @@ -1,5 +1,4 @@ using System.Runtime.CompilerServices; -using Unity.Burst.Intrinsics; using Unity.Mathematics; using MaxMath.Intrinsics; @@ -15,7 +14,7 @@ public static bool2 tobool2(int mask) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.broadcastmask_epi8(mask, MaskType.One, 2)); + return RegisterConversion.ToBool2(Xse.broadcastmask_epi8(mask, MaskType.One, 2)); } else { @@ -33,7 +32,7 @@ public static bool3 tobool3(int mask) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.broadcastmask_epi8(mask, MaskType.One, 3)); + return RegisterConversion.ToBool3(Xse.broadcastmask_epi8(mask, MaskType.One, 3)); } else { @@ -47,7 +46,7 @@ public static bool4 tobool4(int mask) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.broadcastmask_epi8(mask, MaskType.One, 4)); + return RegisterConversion.ToBool4(Xse.broadcastmask_epi8(mask, MaskType.One, 4)); } else { diff --git a/Runtime/Math Lib/Functions/Bitwise/Bit Test/Bit Test and Complement.cs b/Runtime/Math Lib/Functions/Bitwise/Bit Test/Bit Test and Complement.cs index afa728f..8a78b69 100644 --- a/Runtime/Math Lib/Functions/Bitwise/Bit Test/Bit Test and Complement.cs +++ b/Runtime/Math Lib/Functions/Bitwise/Bit Test/Bit Test and Complement.cs @@ -259,7 +259,7 @@ public static bool2 testbitflip(ref byte2 x, byte2 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool2 result = RegisterConversion.ToType(Xse.btc_epi8(ref __ref, i, MaskType.One, 2)); + bool2 result = RegisterConversion.ToBool2(Xse.btc_epi8(ref __ref, i, MaskType.One, 2)); x = __ref; return result; @@ -277,7 +277,7 @@ public static bool3 testbitflip(ref byte3 x, byte3 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool3 result = RegisterConversion.ToType(Xse.btc_epi8(ref __ref, i, MaskType.One, 3)); + bool3 result = RegisterConversion.ToBool3(Xse.btc_epi8(ref __ref, i, MaskType.One, 3)); x = __ref; return result; @@ -295,7 +295,7 @@ public static bool4 testbitflip(ref byte4 x, byte4 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool4 result = RegisterConversion.ToType(Xse.btc_epi8(ref __ref, i, MaskType.One, 4)); + bool4 result = RegisterConversion.ToBool4(Xse.btc_epi8(ref __ref, i, MaskType.One, 4)); x = __ref; return result; @@ -406,7 +406,7 @@ public static bool2 testbitflip(ref ushort2 x, ushort2 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool2 result = RegisterConversion.ToType(Xse.cvtepi16_epi8(Xse.btc_epi16(ref __ref, i, MaskType.One, 2), 2)); + bool2 result = RegisterConversion.ToBool2(Xse.cvtepi16_epi8(Xse.btc_epi16(ref __ref, i, MaskType.One, 2), 2)); x = __ref; return result; @@ -424,7 +424,7 @@ public static bool3 testbitflip(ref ushort3 x, ushort3 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool3 result = RegisterConversion.ToType(Xse.cvtepi16_epi8(Xse.btc_epi16(ref __ref, i, MaskType.One, 3), 3)); + bool3 result = RegisterConversion.ToBool3(Xse.cvtepi16_epi8(Xse.btc_epi16(ref __ref, i, MaskType.One, 3), 3)); x = __ref; return result; @@ -442,7 +442,7 @@ public static bool4 testbitflip(ref ushort4 x, ushort4 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool4 result = RegisterConversion.ToType(Xse.cvtepi16_epi8(Xse.btc_epi16(ref __ref, i, MaskType.One, 4), 4)); + bool4 result = RegisterConversion.ToBool4(Xse.cvtepi16_epi8(Xse.btc_epi16(ref __ref, i, MaskType.One, 4), 4)); x = __ref; return result; @@ -520,8 +520,8 @@ public static bool2 testbitflip(ref uint2 x, uint2 i) if (Sse2.IsSse2Supported) { v128 __ref = RegisterConversion.ToV128(x); - bool2 result = RegisterConversion.ToType(Xse.cvtepi32_epi8(Xse.btc_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 2), 2)); - x = RegisterConversion.ToType(__ref); + bool2 result = RegisterConversion.ToBool2(Xse.cvtepi32_epi8(Xse.btc_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 2), 2)); + x = RegisterConversion.ToUInt2(__ref); return result; } @@ -538,8 +538,8 @@ public static bool3 testbitflip(ref uint3 x, uint3 i) if (Sse2.IsSse2Supported) { v128 __ref = RegisterConversion.ToV128(x); - bool3 result = RegisterConversion.ToType(Xse.cvtepi32_epi8(Xse.btc_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 3), 3)); - x = RegisterConversion.ToType(__ref); + bool3 result = RegisterConversion.ToBool3(Xse.cvtepi32_epi8(Xse.btc_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 3), 3)); + x = RegisterConversion.ToUInt3(__ref); return result; } @@ -556,8 +556,8 @@ public static bool4 testbitflip(ref uint4 x, uint4 i) if (Sse2.IsSse2Supported) { v128 __ref = RegisterConversion.ToV128(x); - bool4 result = RegisterConversion.ToType(Xse.cvtepi32_epi8(Xse.btc_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 4), 4)); - x = RegisterConversion.ToType(__ref); + bool4 result = RegisterConversion.ToBool4(Xse.cvtepi32_epi8(Xse.btc_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 4), 4)); + x = RegisterConversion.ToUInt4(__ref); return result; } @@ -609,7 +609,7 @@ public static bool2 testbitflip(ref ulong2 x, ulong2 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool2 result = RegisterConversion.ToType(Xse.cvtepi64_epi8(Xse.btc_epi64(ref __ref, i, MaskType.One))); + bool2 result = RegisterConversion.ToBool2(Xse.cvtepi64_epi8(Xse.btc_epi64(ref __ref, i, MaskType.One))); x = __ref; return result; @@ -627,7 +627,7 @@ public static bool3 testbitflip(ref ulong3 x, ulong3 i) if (Avx2.IsAvx2Supported) { v256 __ref = x; - bool3 result = RegisterConversion.ToType(Xse.mm256_cvtepi64_epi8(Xse.mm256_btc_epi64(ref __ref, i, MaskType.One))); + bool3 result = RegisterConversion.ToBool3(Xse.mm256_cvtepi64_epi8(Xse.mm256_btc_epi64(ref __ref, i, MaskType.One))); x = __ref; return result; @@ -649,7 +649,7 @@ public static bool4 testbitflip(ref ulong4 x, ulong4 i) if (Avx2.IsAvx2Supported) { v256 __ref = x; - bool4 result = RegisterConversion.ToType(Xse.mm256_cvtepi64_epi8(Xse.mm256_btc_epi64(ref __ref, i, MaskType.One))); + bool4 result = RegisterConversion.ToBool4(Xse.mm256_cvtepi64_epi8(Xse.mm256_btc_epi64(ref __ref, i, MaskType.One))); x = __ref; return result; diff --git a/Runtime/Math Lib/Functions/Bitwise/Bit Test/Bit Test and Reset.cs b/Runtime/Math Lib/Functions/Bitwise/Bit Test/Bit Test and Reset.cs index d40e379..13de229 100644 --- a/Runtime/Math Lib/Functions/Bitwise/Bit Test/Bit Test and Reset.cs +++ b/Runtime/Math Lib/Functions/Bitwise/Bit Test/Bit Test and Reset.cs @@ -2,7 +2,7 @@ using Unity.Burst.CompilerServices; using Unity.Burst.Intrinsics; using Unity.Mathematics; -using MaxMath.Intrinsics; +using MaxMath.Intrinsics; using static Unity.Burst.Intrinsics.X86; @@ -259,7 +259,7 @@ public static bool2 testbitreset(ref byte2 x, byte2 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool2 result = RegisterConversion.ToType(Xse.btr_epi8(ref __ref, i, MaskType.One, 2)); + bool2 result = RegisterConversion.ToBool2(Xse.btr_epi8(ref __ref, i, MaskType.One, 2)); x = __ref; return result; @@ -277,7 +277,7 @@ public static bool3 testbitreset(ref byte3 x, byte3 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool3 result = RegisterConversion.ToType(Xse.btr_epi8(ref __ref, i, MaskType.One, 3)); + bool3 result = RegisterConversion.ToBool3(Xse.btr_epi8(ref __ref, i, MaskType.One, 3)); x = __ref; return result; @@ -295,7 +295,7 @@ public static bool4 testbitreset(ref byte4 x, byte4 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool4 result = RegisterConversion.ToType(Xse.btr_epi8(ref __ref, i, MaskType.One, 4)); + bool4 result = RegisterConversion.ToBool4(Xse.btr_epi8(ref __ref, i, MaskType.One, 4)); x = __ref; return result; @@ -406,7 +406,7 @@ public static bool2 testbitreset(ref ushort2 x, ushort2 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool2 result = RegisterConversion.ToType(Xse.cvtepi16_epi8(Xse.btr_epi16(ref __ref, i, MaskType.One, 2), 2)); + bool2 result = RegisterConversion.ToBool2(Xse.cvtepi16_epi8(Xse.btr_epi16(ref __ref, i, MaskType.One, 2), 2)); x = __ref; return result; @@ -424,7 +424,7 @@ public static bool3 testbitreset(ref ushort3 x, ushort3 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool3 result = RegisterConversion.ToType(Xse.cvtepi16_epi8(Xse.btr_epi16(ref __ref, i, MaskType.One, 3), 3)); + bool3 result = RegisterConversion.ToBool3(Xse.cvtepi16_epi8(Xse.btr_epi16(ref __ref, i, MaskType.One, 3), 3)); x = __ref; return result; @@ -442,7 +442,7 @@ public static bool4 testbitreset(ref ushort4 x, ushort4 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool4 result = RegisterConversion.ToType(Xse.cvtepi16_epi8(Xse.btr_epi16(ref __ref, i, MaskType.One, 4), 4)); + bool4 result = RegisterConversion.ToBool4(Xse.cvtepi16_epi8(Xse.btr_epi16(ref __ref, i, MaskType.One, 4), 4)); x = __ref; return result; @@ -520,8 +520,8 @@ public static bool2 testbitreset(ref uint2 x, uint2 i) if (Sse2.IsSse2Supported) { v128 __ref = RegisterConversion.ToV128(x); - bool2 result = RegisterConversion.ToType(Xse.cvtepi32_epi8(Xse.btr_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 2), 2)); - x = RegisterConversion.ToType(__ref); + bool2 result = RegisterConversion.ToBool2(Xse.cvtepi32_epi8(Xse.btr_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 2), 2)); + x = RegisterConversion.ToUInt2(__ref); return result; } @@ -538,8 +538,8 @@ public static bool3 testbitreset(ref uint3 x, uint3 i) if (Sse2.IsSse2Supported) { v128 __ref = RegisterConversion.ToV128(x); - bool3 result = RegisterConversion.ToType(Xse.cvtepi32_epi8(Xse.btr_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 3), 3)); - x = RegisterConversion.ToType(__ref); + bool3 result = RegisterConversion.ToBool3(Xse.cvtepi32_epi8(Xse.btr_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 3), 3)); + x = RegisterConversion.ToUInt3(__ref); return result; } @@ -556,8 +556,8 @@ public static bool4 testbitreset(ref uint4 x, uint4 i) if (Sse2.IsSse2Supported) { v128 __ref = RegisterConversion.ToV128(x); - bool4 result = RegisterConversion.ToType(Xse.cvtepi32_epi8(Xse.btr_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 4), 4)); - x = RegisterConversion.ToType(__ref); + bool4 result = RegisterConversion.ToBool4(Xse.cvtepi32_epi8(Xse.btr_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 4), 4)); + x = RegisterConversion.ToUInt4(__ref); return result; } @@ -609,7 +609,7 @@ public static bool2 testbitreset(ref ulong2 x, ulong2 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool2 result = RegisterConversion.ToType(Xse.cvtepi64_epi8(Xse.btr_epi64(ref __ref, i, MaskType.One))); + bool2 result = RegisterConversion.ToBool2(Xse.cvtepi64_epi8(Xse.btr_epi64(ref __ref, i, MaskType.One))); x = __ref; return result; @@ -627,7 +627,7 @@ public static bool3 testbitreset(ref ulong3 x, ulong3 i) if (Avx2.IsAvx2Supported) { v256 __ref = x; - bool3 result = RegisterConversion.ToType(Xse.mm256_cvtepi64_epi8(Xse.mm256_btr_epi64(ref __ref, i, MaskType.One))); + bool3 result = RegisterConversion.ToBool3(Xse.mm256_cvtepi64_epi8(Xse.mm256_btr_epi64(ref __ref, i, MaskType.One))); x = __ref; return result; @@ -649,7 +649,7 @@ public static bool4 testbitreset(ref ulong4 x, ulong4 i) if (Avx2.IsAvx2Supported) { v256 __ref = x; - bool4 result = RegisterConversion.ToType(Xse.mm256_cvtepi64_epi8(Xse.mm256_btr_epi64(ref __ref, i, MaskType.One))); + bool4 result = RegisterConversion.ToBool4(Xse.mm256_cvtepi64_epi8(Xse.mm256_btr_epi64(ref __ref, i, MaskType.One))); x = __ref; return result; diff --git a/Runtime/Math Lib/Functions/Bitwise/Bit Test/Bit Test and Set.cs b/Runtime/Math Lib/Functions/Bitwise/Bit Test/Bit Test and Set.cs index 769ad74..82fbd39 100644 --- a/Runtime/Math Lib/Functions/Bitwise/Bit Test/Bit Test and Set.cs +++ b/Runtime/Math Lib/Functions/Bitwise/Bit Test/Bit Test and Set.cs @@ -259,7 +259,7 @@ public static bool2 testbitset(ref byte2 x, byte2 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool2 result = RegisterConversion.ToType(Xse.bts_epi8(ref __ref, i, MaskType.One, 2)); + bool2 result = RegisterConversion.ToBool2(Xse.bts_epi8(ref __ref, i, MaskType.One, 2)); x = __ref; return result; @@ -277,7 +277,7 @@ public static bool3 testbitset(ref byte3 x, byte3 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool3 result = RegisterConversion.ToType(Xse.bts_epi8(ref __ref, i, MaskType.One, 3)); + bool3 result = RegisterConversion.ToBool3(Xse.bts_epi8(ref __ref, i, MaskType.One, 3)); x = __ref; return result; @@ -295,7 +295,7 @@ public static bool4 testbitset(ref byte4 x, byte4 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool4 result = RegisterConversion.ToType(Xse.bts_epi8(ref __ref, i, MaskType.One, 4)); + bool4 result = RegisterConversion.ToBool4(Xse.bts_epi8(ref __ref, i, MaskType.One, 4)); x = __ref; return result; @@ -406,7 +406,7 @@ public static bool2 testbitset(ref ushort2 x, ushort2 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool2 result = RegisterConversion.ToType(Xse.cvtepi16_epi8(Xse.bts_epi16(ref __ref, i, MaskType.One, 2), 2)); + bool2 result = RegisterConversion.ToBool2(Xse.cvtepi16_epi8(Xse.bts_epi16(ref __ref, i, MaskType.One, 2), 2)); x = __ref; return result; @@ -424,7 +424,7 @@ public static bool3 testbitset(ref ushort3 x, ushort3 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool3 result = RegisterConversion.ToType(Xse.cvtepi16_epi8(Xse.bts_epi16(ref __ref, i, MaskType.One, 3), 3)); + bool3 result = RegisterConversion.ToBool3(Xse.cvtepi16_epi8(Xse.bts_epi16(ref __ref, i, MaskType.One, 3), 3)); x = __ref; return result; @@ -442,7 +442,7 @@ public static bool4 testbitset(ref ushort4 x, ushort4 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool4 result = RegisterConversion.ToType(Xse.cvtepi16_epi8(Xse.bts_epi16(ref __ref, i, MaskType.One, 4), 4)); + bool4 result = RegisterConversion.ToBool4(Xse.cvtepi16_epi8(Xse.bts_epi16(ref __ref, i, MaskType.One, 4), 4)); x = __ref; return result; @@ -520,8 +520,8 @@ public static bool2 testbitset(ref uint2 x, uint2 i) if (Sse2.IsSse2Supported) { v128 __ref = RegisterConversion.ToV128(x); - bool2 result = RegisterConversion.ToType(Xse.cvtepi32_epi8(Xse.bts_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 2), 2)); - x = RegisterConversion.ToType(__ref); + bool2 result = RegisterConversion.ToBool2(Xse.cvtepi32_epi8(Xse.bts_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 2), 2)); + x = RegisterConversion.ToUInt2(__ref); return result; } @@ -538,8 +538,8 @@ public static bool3 testbitset(ref uint3 x, uint3 i) if (Sse2.IsSse2Supported) { v128 __ref = RegisterConversion.ToV128(x); - bool3 result = RegisterConversion.ToType(Xse.cvtepi32_epi8(Xse.bts_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 3), 3)); - x = RegisterConversion.ToType(__ref); + bool3 result = RegisterConversion.ToBool3(Xse.cvtepi32_epi8(Xse.bts_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 3), 3)); + x = RegisterConversion.ToUInt3(__ref); return result; } @@ -556,8 +556,8 @@ public static bool4 testbitset(ref uint4 x, uint4 i) if (Sse2.IsSse2Supported) { v128 __ref = RegisterConversion.ToV128(x); - bool4 result = RegisterConversion.ToType(Xse.cvtepi32_epi8(Xse.bts_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 4), 4)); - x = RegisterConversion.ToType(__ref); + bool4 result = RegisterConversion.ToBool4(Xse.cvtepi32_epi8(Xse.bts_epi32(ref __ref, RegisterConversion.ToV128(i), MaskType.One, 4), 4)); + x = RegisterConversion.ToUInt4(__ref); return result; } @@ -609,7 +609,7 @@ public static bool2 testbitset(ref ulong2 x, ulong2 i) if (Sse2.IsSse2Supported) { v128 __ref = x; - bool2 result = RegisterConversion.ToType(Xse.cvtepi64_epi8(Xse.bts_epi64(ref __ref, i, MaskType.One))); + bool2 result = RegisterConversion.ToBool2(Xse.cvtepi64_epi8(Xse.bts_epi64(ref __ref, i, MaskType.One))); x = __ref; return result; @@ -627,7 +627,7 @@ public static bool3 testbitset(ref ulong3 x, ulong3 i) if (Avx2.IsAvx2Supported) { v256 __ref = x; - bool3 result = RegisterConversion.ToType(Xse.mm256_cvtepi64_epi8(Xse.mm256_bts_epi64(ref __ref, i, MaskType.One))); + bool3 result = RegisterConversion.ToBool3(Xse.mm256_cvtepi64_epi8(Xse.mm256_bts_epi64(ref __ref, i, MaskType.One))); x = __ref; return result; @@ -649,7 +649,7 @@ public static bool4 testbitset(ref ulong4 x, ulong4 i) if (Avx2.IsAvx2Supported) { v256 __ref = x; - bool4 result = RegisterConversion.ToType(Xse.mm256_cvtepi64_epi8(Xse.mm256_bts_epi64(ref __ref, i, MaskType.One))); + bool4 result = RegisterConversion.ToBool4(Xse.mm256_cvtepi64_epi8(Xse.mm256_bts_epi64(ref __ref, i, MaskType.One))); x = __ref; return result; diff --git a/Runtime/Math Lib/Functions/Bitwise/Bit Test/Bit Test.cs b/Runtime/Math Lib/Functions/Bitwise/Bit Test/Bit Test.cs index 8dc44aa..e123d73 100644 --- a/Runtime/Math Lib/Functions/Bitwise/Bit Test/Bit Test.cs +++ b/Runtime/Math Lib/Functions/Bitwise/Bit Test/Bit Test.cs @@ -242,7 +242,7 @@ public static bool2 testbit(byte2 x, byte2 i) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.bt_epi8(x, i, MaskType.One, 2)); + return RegisterConversion.ToBool2(Xse.bt_epi8(x, i, MaskType.One, 2)); } else { @@ -256,7 +256,7 @@ public static bool3 testbit(byte3 x, byte3 i) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.bt_epi8(x, i, MaskType.One, 3)); + return RegisterConversion.ToBool3(Xse.bt_epi8(x, i, MaskType.One, 3)); } else { @@ -270,7 +270,7 @@ public static bool4 testbit(byte4 x, byte4 i) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.bt_epi8(x, i, MaskType.One, 4)); + return RegisterConversion.ToBool4(Xse.bt_epi8(x, i, MaskType.One, 4)); } else { @@ -356,7 +356,7 @@ public static bool2 testbit(ushort2 x, ushort2 i) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi16_epi8(Xse.bt_epi16(x, i, MaskType.One, 2), 2)); + return RegisterConversion.ToBool2(Xse.cvtepi16_epi8(Xse.bt_epi16(x, i, MaskType.One, 2), 2)); } else { @@ -370,7 +370,7 @@ public static bool3 testbit(ushort3 x, ushort3 i) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi16_epi8(Xse.bt_epi16(x, i, MaskType.One, 3), 3)); + return RegisterConversion.ToBool3(Xse.cvtepi16_epi8(Xse.bt_epi16(x, i, MaskType.One, 3), 3)); } else { @@ -384,7 +384,7 @@ public static bool4 testbit(ushort4 x, ushort4 i) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi16_epi8(Xse.bt_epi16(x, i, MaskType.One, 4), 4)); + return RegisterConversion.ToBool4(Xse.cvtepi16_epi8(Xse.bt_epi16(x, i, MaskType.One, 4), 4)); } else { @@ -441,7 +441,7 @@ public static bool2 testbit(uint2 x, uint2 i) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi32_epi8(Xse.bt_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(i), MaskType.One, 2), 2)); + return RegisterConversion.ToBool2(Xse.cvtepi32_epi8(Xse.bt_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(i), MaskType.One, 2), 2)); } else { @@ -455,7 +455,7 @@ public static bool3 testbit(uint3 x, uint3 i) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi32_epi8(Xse.bt_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(i), MaskType.One, 3), 3)); + return RegisterConversion.ToBool3(Xse.cvtepi32_epi8(Xse.bt_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(i), MaskType.One, 3), 3)); } else { @@ -469,7 +469,7 @@ public static bool4 testbit(uint4 x, uint4 i) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi32_epi8(Xse.bt_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(i), MaskType.One, 4), 4)); + return RegisterConversion.ToBool4(Xse.cvtepi32_epi8(Xse.bt_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(i), MaskType.One, 4), 4)); } else { @@ -505,7 +505,7 @@ public static bool2 testbit(ulong2 x, ulong2 i) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi64_epi8(Xse.bt_epi64(x, i, MaskType.One))); + return RegisterConversion.ToBool2(Xse.cvtepi64_epi8(Xse.bt_epi64(x, i, MaskType.One))); } else { @@ -519,7 +519,7 @@ public static bool3 testbit(ulong3 x, ulong3 i) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi8(Xse.mm256_bt_epi64(x, i, MaskType.One, 3))); + return RegisterConversion.ToBool3(Xse.mm256_cvtepi64_epi8(Xse.mm256_bt_epi64(x, i, MaskType.One, 3))); } else { @@ -533,7 +533,7 @@ public static bool4 testbit(ulong4 x, ulong4 i) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi8(Xse.mm256_bt_epi64(x, i, MaskType.One, 4))); + return RegisterConversion.ToBool4(Xse.mm256_cvtepi64_epi8(Xse.mm256_bt_epi64(x, i, MaskType.One, 4))); } else { diff --git a/Runtime/Math Lib/Functions/Bitwise/Boolean Operations/AndNot.cs b/Runtime/Math Lib/Functions/Bitwise/Boolean Operations/AndNot.cs index cdac73d..2c35640 100644 --- a/Runtime/Math Lib/Functions/Bitwise/Boolean Operations/AndNot.cs +++ b/Runtime/Math Lib/Functions/Bitwise/Boolean Operations/AndNot.cs @@ -1,6 +1,5 @@ using System.Runtime.CompilerServices; using Unity.Mathematics; -using Unity.Burst.Intrinsics; using DevTools; using static Unity.Burst.Intrinsics.X86; @@ -42,7 +41,7 @@ public static bool2 andnot(bool2 left, bool2 right) if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Sse2.andnot_si128(RegisterConversion.ToV128(right), RegisterConversion.ToV128(left))); + return RegisterConversion.ToBool2(Sse2.andnot_si128(RegisterConversion.ToV128(right), RegisterConversion.ToV128(left))); } else { @@ -63,7 +62,7 @@ public static bool3 andnot(bool3 left, bool3 right) if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Sse2.andnot_si128(RegisterConversion.ToV128(right), RegisterConversion.ToV128(left))); + return RegisterConversion.ToBool3(Sse2.andnot_si128(RegisterConversion.ToV128(right), RegisterConversion.ToV128(left))); } else { @@ -86,7 +85,7 @@ public static bool4 andnot(bool4 left, bool4 right) if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Sse2.andnot_si128(RegisterConversion.ToV128(right), RegisterConversion.ToV128(left))); + return RegisterConversion.ToBool4(Sse2.andnot_si128(RegisterConversion.ToV128(right), RegisterConversion.ToV128(left))); } else { @@ -528,7 +527,7 @@ public static int2 andnot(int2 left, int2 right) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Sse2.andnot_si128(RegisterConversion.ToV128(right), RegisterConversion.ToV128(left))); + return RegisterConversion.ToInt2(Sse2.andnot_si128(RegisterConversion.ToV128(right), RegisterConversion.ToV128(left))); } else { @@ -542,7 +541,7 @@ public static int3 andnot(int3 left, int3 right) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Sse2.andnot_si128(RegisterConversion.ToV128(right), RegisterConversion.ToV128(left))); + return RegisterConversion.ToInt3(Sse2.andnot_si128(RegisterConversion.ToV128(right), RegisterConversion.ToV128(left))); } else { @@ -556,7 +555,7 @@ public static int4 andnot(int4 left, int4 right) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Sse2.andnot_si128(RegisterConversion.ToV128(right), RegisterConversion.ToV128(left))); + return RegisterConversion.ToInt4(Sse2.andnot_si128(RegisterConversion.ToV128(right), RegisterConversion.ToV128(left))); } else { diff --git a/Runtime/Math Lib/Functions/Bitwise/Counting Bits/Leading Zero Count.cs b/Runtime/Math Lib/Functions/Bitwise/Counting Bits/Leading Zero Count.cs index 5ff3468..ea6886a 100644 --- a/Runtime/Math Lib/Functions/Bitwise/Counting Bits/Leading Zero Count.cs +++ b/Runtime/Math Lib/Functions/Bitwise/Counting Bits/Leading Zero Count.cs @@ -147,15 +147,15 @@ public static v128 lzcnt_epi32(v128 a, byte elements = 4) v128 loA = cvt2x2epu32_epi64(a, out v128 hiA); loA = Sse2.add_epi64(loA, Sse2.set1_epi64x(4_841_369_599_423_283_200L)); hiA = Sse2.add_epi64(hiA, Sse2.set1_epi64x(4_841_369_599_423_283_200L)); - loA = Sse2.sub_pd(loA, Sse2.set1_pd(LIMIT_PRECISE_I32_F64)); - hiA = Sse2.sub_pd(hiA, Sse2.set1_pd(LIMIT_PRECISE_I32_F64)); + loA = Sse2.sub_pd(loA, Sse2.set1_pd(LIMIT_PRECISE_U64_F64)); + hiA = Sse2.sub_pd(hiA, Sse2.set1_pd(LIMIT_PRECISE_U64_F64)); result = Sse.shuffle_ps(loA, hiA, Sse.SHUFFLE(3, 1, 3, 1)); } else { result = cvtepu32_epi64(a); result = Sse2.add_epi64(result, Sse2.set1_epi64x(4_841_369_599_423_283_200L)); - result = Sse2.sub_pd(result, Sse2.set1_pd(LIMIT_PRECISE_I32_F64)); + result = Sse2.sub_pd(result, Sse2.set1_pd(LIMIT_PRECISE_U64_F64)); result = Sse2.shuffle_epi32(result, Sse.SHUFFLE(0, 0, 3, 1)); } @@ -177,8 +177,8 @@ public static v256 mm256_lzcnt_epi32(v256 a) v256 loA = mm256_cvt2x2epu32_epi64(a, out v256 hiA); loA = Avx2.mm256_add_epi64(loA, Avx.mm256_set1_epi64x(4_841_369_599_423_283_200L)); hiA = Avx2.mm256_add_epi64(hiA, Avx.mm256_set1_epi64x(4_841_369_599_423_283_200L)); - loA = Avx.mm256_sub_pd(loA, Avx.mm256_set1_pd(LIMIT_PRECISE_I32_F64)); - hiA = Avx.mm256_sub_pd(hiA, Avx.mm256_set1_pd(LIMIT_PRECISE_I32_F64)); + loA = Avx.mm256_sub_pd(loA, Avx.mm256_set1_pd(LIMIT_PRECISE_U64_F64)); + hiA = Avx.mm256_sub_pd(hiA, Avx.mm256_set1_pd(LIMIT_PRECISE_U64_F64)); v256 result = Avx.mm256_shuffle_ps(loA, hiA, Sse.SHUFFLE(3, 1, 3, 1)); result = Avx2.mm256_srai_epi32(result, 52 - 32); @@ -218,8 +218,8 @@ public static v256 mm256_lzcnt_epi64(v256 a) v256 bits = mm256_blendv_si256(y, Avx2.mm256_blend_epi32(ZERO, a, 0b0101_0101), cmp); v256 offset = mm256_blendv_si256(new v256(0x041Eul), new v256(0x043Eul), cmp); - bits = Avx2.mm256_add_epi64(bits, new v256(LIMIT_PRECISE_I32_F64)); - bits = Avx.mm256_sub_pd(bits, new v256(LIMIT_PRECISE_I32_F64)); + bits = Avx2.mm256_add_epi64(bits, new v256(LIMIT_PRECISE_U64_F64)); + bits = Avx.mm256_sub_pd(bits, new v256(LIMIT_PRECISE_U64_F64)); bits = Avx2.mm256_sub_epi64(offset, Avx2.mm256_srli_epi64(bits, 52)); return mm256_blendv_si256(bits, new v256(64ul), Avx2.mm256_cmpeq_epi64(a, ZERO)); diff --git a/Runtime/Math Lib/Functions/Bitwise/Counting Bits/Trailing Zero Count.cs b/Runtime/Math Lib/Functions/Bitwise/Counting Bits/Trailing Zero Count.cs index b3f74a9..039043d 100644 --- a/Runtime/Math Lib/Functions/Bitwise/Counting Bits/Trailing Zero Count.cs +++ b/Runtime/Math Lib/Functions/Bitwise/Counting Bits/Trailing Zero Count.cs @@ -115,15 +115,15 @@ public static v128 tzcnt_epi32(v128 a, byte elements = 4) v128 loA = cvt2x2epu32_epi64(blsi_epi32(a), out v128 hiA); loA = Sse2.add_epi64(loA, Sse2.set1_epi64x(4_841_369_599_423_283_200L)); hiA = Sse2.add_epi64(hiA, Sse2.set1_epi64x(4_841_369_599_423_283_200L)); - loA = Sse2.sub_pd(loA, Sse2.set1_pd(LIMIT_PRECISE_I32_F64)); - hiA = Sse2.sub_pd(hiA, Sse2.set1_pd(LIMIT_PRECISE_I32_F64)); + loA = Sse2.sub_pd(loA, Sse2.set1_pd(LIMIT_PRECISE_U64_F64)); + hiA = Sse2.sub_pd(hiA, Sse2.set1_pd(LIMIT_PRECISE_U64_F64)); result = Sse.shuffle_ps(loA, hiA, Sse.SHUFFLE(3, 1, 3, 1)); } else { result = cvtepu32_epi64(blsi_epi32(a)); result = Sse2.add_epi64(result, Sse2.set1_epi64x(4_841_369_599_423_283_200L)); - result = Sse2.sub_pd(result, Sse2.set1_pd(LIMIT_PRECISE_I32_F64)); + result = Sse2.sub_pd(result, Sse2.set1_pd(LIMIT_PRECISE_U64_F64)); result = Sse2.shuffle_epi32(result, Sse.SHUFFLE(0, 0, 3, 1)); } @@ -145,8 +145,8 @@ public static v256 mm256_tzcnt_epi32(v256 a) v256 loA = mm256_cvt2x2epu32_epi64(mm256_blsi_epi32(a), out v256 hiA); loA = Avx2.mm256_add_epi64(loA, Avx.mm256_set1_epi64x(4_841_369_599_423_283_200L)); hiA = Avx2.mm256_add_epi64(hiA, Avx.mm256_set1_epi64x(4_841_369_599_423_283_200L)); - loA = Avx.mm256_sub_pd(loA, Avx.mm256_set1_pd(LIMIT_PRECISE_I32_F64)); - hiA = Avx.mm256_sub_pd(hiA, Avx.mm256_set1_pd(LIMIT_PRECISE_I32_F64)); + loA = Avx.mm256_sub_pd(loA, Avx.mm256_set1_pd(LIMIT_PRECISE_U64_F64)); + hiA = Avx.mm256_sub_pd(hiA, Avx.mm256_set1_pd(LIMIT_PRECISE_U64_F64)); v256 result = Avx.mm256_shuffle_ps(loA, hiA, Sse.SHUFFLE(3, 1, 3, 1)); result = Avx2.mm256_srai_epi32(result, 52 - 32); @@ -188,8 +188,8 @@ public static v256 mm256_tzcnt_epi64(v256 a) v256 bits = mm256_blendv_si256(y, Avx2.mm256_srli_epi64(blsi, 32), cmp); v256 offset = mm256_blendv_si256(new v256(0x03FFul), new v256(0x03DFul), cmp); - bits = Avx2.mm256_add_epi64(bits, new v256(LIMIT_PRECISE_I32_F64)); - bits = Avx.mm256_sub_pd(bits, new v256(LIMIT_PRECISE_I32_F64)); + bits = Avx2.mm256_add_epi64(bits, new v256(LIMIT_PRECISE_U64_F64)); + bits = Avx.mm256_sub_pd(bits, new v256(LIMIT_PRECISE_U64_F64)); bits = Avx2.mm256_sub_epi64(Avx2.mm256_srli_epi64(bits, 52), offset); v256 aZero = Avx2.mm256_cmpeq_epi64(a, ZERO); diff --git a/Runtime/Math Lib/Functions/Bitwise/Transform/Reverse Bits.cs b/Runtime/Math Lib/Functions/Bitwise/Transform/Reverse Bits.cs index eb04551..e8dc58e 100644 --- a/Runtime/Math Lib/Functions/Bitwise/Transform/Reverse Bits.cs +++ b/Runtime/Math Lib/Functions/Bitwise/Transform/Reverse Bits.cs @@ -1,6 +1,5 @@ using System.Runtime.CompilerServices; using Unity.Mathematics; -using Unity.Burst.Intrinsics; namespace MaxMath { diff --git a/Runtime/Math Lib/Functions/Bitwise/Transform/Reverse Bytes.cs b/Runtime/Math Lib/Functions/Bitwise/Transform/Reverse Bytes.cs index 302dd1b..e6fab55 100644 --- a/Runtime/Math Lib/Functions/Bitwise/Transform/Reverse Bytes.cs +++ b/Runtime/Math Lib/Functions/Bitwise/Transform/Reverse Bytes.cs @@ -205,7 +205,7 @@ public static uint2 reversebytes(uint2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.bswap_epi32(RegisterConversion.ToV128(x))); + return RegisterConversion.ToUInt2(Xse.bswap_epi32(RegisterConversion.ToV128(x))); } else { @@ -219,7 +219,7 @@ public static uint3 reversebytes(uint3 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.bswap_epi32(RegisterConversion.ToV128(x))); + return RegisterConversion.ToUInt3(Xse.bswap_epi32(RegisterConversion.ToV128(x))); } else { @@ -233,7 +233,7 @@ public static uint4 reversebytes(uint4 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.bswap_epi32(RegisterConversion.ToV128(x))); + return RegisterConversion.ToUInt4(Xse.bswap_epi32(RegisterConversion.ToV128(x))); } else { diff --git a/Runtime/Math Lib/Functions/Bitwise/Transform/Rotate (varying).cs b/Runtime/Math Lib/Functions/Bitwise/Transform/Rotate (varying).cs index d95702d..5d3299b 100644 --- a/Runtime/Math Lib/Functions/Bitwise/Transform/Rotate (varying).cs +++ b/Runtime/Math Lib/Functions/Bitwise/Transform/Rotate (varying).cs @@ -5,7 +5,7 @@ using static Unity.Burst.Intrinsics.X86; - + namespace MaxMath { namespace Intrinsics @@ -684,7 +684,7 @@ public static int2 ror(int2 x, int2 n, Promise inRange = Promise.Nothing) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.rorv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), inRange.Promises(Promise.NoOverflow), 2)); + return RegisterConversion.ToInt2(Xse.rorv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), inRange.Promises(Promise.NoOverflow), 2)); } else { @@ -699,7 +699,7 @@ public static int3 ror(int3 x, int3 n, Promise inRange = Promise.Nothing) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.rorv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), inRange.Promises(Promise.NoOverflow), 3)); + return RegisterConversion.ToInt3(Xse.rorv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), inRange.Promises(Promise.NoOverflow), 3)); } else { @@ -714,7 +714,7 @@ public static int4 ror(int4 x, int4 n, Promise inRange = Promise.Nothing) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.rorv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), inRange.Promises(Promise.NoOverflow), 4)); + return RegisterConversion.ToInt4(Xse.rorv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), inRange.Promises(Promise.NoOverflow), 4)); } else { @@ -1163,7 +1163,7 @@ public static int2 rol(int2 x, int2 n, Promise inRange = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.rolv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), inRange.Promises(Promise.NoOverflow), 2)); + return RegisterConversion.ToInt2(Xse.rolv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), inRange.Promises(Promise.NoOverflow), 2)); } else { @@ -1178,7 +1178,7 @@ public static int3 rol(int3 x, int3 n, Promise inRange = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.rolv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), inRange.Promises(Promise.NoOverflow), 3)); + return RegisterConversion.ToInt3(Xse.rolv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), inRange.Promises(Promise.NoOverflow), 3)); } else { @@ -1193,7 +1193,7 @@ public static int4 rol(int4 x, int4 n, Promise inRange = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.rolv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), inRange.Promises(Promise.NoOverflow), 4)); + return RegisterConversion.ToInt4(Xse.rolv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), inRange.Promises(Promise.NoOverflow), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Bitwise/Transform/Shift (varying).cs b/Runtime/Math Lib/Functions/Bitwise/Transform/Shift (varying).cs index 68a571b..3aa6e8e 100644 --- a/Runtime/Math Lib/Functions/Bitwise/Transform/Shift (varying).cs +++ b/Runtime/Math Lib/Functions/Bitwise/Transform/Shift (varying).cs @@ -839,7 +839,7 @@ public static v128 srav_epi8(v128 a, v128 b, byte elements = 16) if (constexpr.ALL_SAME_EPU8(b, elements)) { - return srai_epi8(a, b.Byte0); + return srai_epi8(a, b.Byte0, elements); } if (Ssse3.IsSsse3Supported && Constant.IsConstantExpression(a.Byte0) && constexpr.ALL_SAME_EPU8(a, elements)) @@ -1205,6 +1205,10 @@ public static v128 srav_epi64(v128 a, v128 b) { return srai_epi64(a, b.SInt0); } + if (constexpr.ALL_GE_EPI64(a, 0)) + { + return srlv_epi64(a, b); + } if (Avx2.IsAvx2Supported) { @@ -1249,7 +1253,11 @@ public static v256 mm256_srav_epi64(v256 a, v256 b, byte elements = 4) { return mm256_srai_epi64(a, b.SInt0); } - + + if (constexpr.ALL_GE_EPI64(a, 0, elements)) + { + return Avx2.mm256_srlv_epi64(a, b); + } if (constexpr.ALL_LT_EPI64(b, 32, elements)) { v256 shiftLo = Avx2.mm256_srlv_epi64(a, b); @@ -1278,7 +1286,7 @@ public static v256 mm256_srav_epi64(v256 a, v256 b, byte elements = 4) unsafe public static partial class maxmath { - /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte2 shl(byte2 x, byte2 n) { @@ -1292,7 +1300,7 @@ public static byte2 shl(byte2 x, byte2 n) } } - /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte3 shl(byte3 x, byte3 n) { @@ -1306,7 +1314,7 @@ public static byte3 shl(byte3 x, byte3 n) } } - /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte4 shl(byte4 x, byte4 n) { @@ -1320,7 +1328,7 @@ public static byte4 shl(byte4 x, byte4 n) } } - /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte8 shl(byte8 x, byte8 n) { @@ -1334,7 +1342,7 @@ public static byte8 shl(byte8 x, byte8 n) } } - /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte16 shl(byte16 x, byte16 n) { @@ -1348,7 +1356,7 @@ public static byte16 shl(byte16 x, byte16 n) } } - /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte32 shl(byte32 x, byte32 n) { @@ -1362,42 +1370,42 @@ public static byte32 shl(byte32 x, byte32 n) } } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte2 shl(byte2 x, sbyte2 n) { return shl(x, (byte2)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte3 shl(byte3 x, sbyte3 n) { return shl(x, (byte3)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte4 shl(byte4 x, sbyte4 n) { return shl(x, (byte4)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte8 shl(byte8 x, sbyte8 n) { return shl(x, (byte8)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte16 shl(byte16 x, sbyte16 n) { return shl(x, (byte16)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte32 shl(byte32 x, sbyte32 n) { @@ -1405,42 +1413,42 @@ public static byte32 shl(byte32 x, sbyte32 n) } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte2 shl(sbyte2 x, sbyte2 n) { return (sbyte2)shl((byte2)x, (byte2)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte3 shl(sbyte3 x, sbyte3 n) { return (sbyte3)shl((byte3)x, (byte3)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte4 shl(sbyte4 x, sbyte4 n) { return (sbyte4)shl((byte4)x, (byte4)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte8 shl(sbyte8 x, sbyte8 n) { return (sbyte8)shl((byte8)x, (byte8)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte16 shl(sbyte16 x, sbyte16 n) { return (sbyte16)shl((byte16)x, (byte16)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte32 shl(sbyte32 x, sbyte32 n) { @@ -1448,7 +1456,7 @@ public static sbyte32 shl(sbyte32 x, sbyte32 n) } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short2 shl(short2 x, short2 n) { @@ -1462,7 +1470,7 @@ public static short2 shl(short2 x, short2 n) } } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short3 shl(short3 x, short3 n) { @@ -1476,7 +1484,7 @@ public static short3 shl(short3 x, short3 n) } } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short4 shl(short4 x, short4 n) { @@ -1490,7 +1498,7 @@ public static short4 shl(short4 x, short4 n) } } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short8 shl(short8 x, short8 n) { @@ -1504,7 +1512,7 @@ public static short8 shl(short8 x, short8 n) } } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short16 shl(short16 x, short16 n) { @@ -1519,70 +1527,70 @@ public static short16 shl(short16 x, short16 n) } - /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort2 shl(ushort2 x, ushort2 n) { return (ushort2)shl((short2)x, (short2)n); } - /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort3 shl(ushort3 x, ushort3 n) { return (ushort3)shl((short3)x, (short3)n); } - /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort4 shl(ushort4 x, ushort4 n) { return (ushort4)shl((short4)x, (short4)n); } - /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort8 shl(ushort8 x, ushort8 n) { return (ushort8)shl((short8)x, (short8)n); } - /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort16 shl(ushort16 x, ushort16 n) { return (ushort16)shl((short16)x, (short16)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort2 shl(ushort2 x, short2 n) { return shl(x, (ushort2)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort3 shl(ushort3 x, short3 n) { return shl(x, (ushort3)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort4 shl(ushort4 x, short4 n) { return shl(x, (ushort4)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort8 shl(ushort8 x, short8 n) { return shl(x, (ushort8)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort16 shl(ushort16 x, short16 n) { @@ -1590,13 +1598,13 @@ public static ushort16 shl(ushort16 x, short16 n) } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int2 shl(int2 x, int2 n) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.sllv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n))); + return RegisterConversion.ToInt2(Xse.sllv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n))); } else { @@ -1604,13 +1612,13 @@ public static int2 shl(int2 x, int2 n) } } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int3 shl(int3 x, int3 n) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.sllv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n))); + return RegisterConversion.ToInt3(Xse.sllv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n))); } else { @@ -1618,13 +1626,13 @@ public static int3 shl(int3 x, int3 n) } } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int4 shl(int4 x, int4 n) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.sllv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n))); + return RegisterConversion.ToInt4(Xse.sllv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n))); } else { @@ -1632,7 +1640,7 @@ public static int4 shl(int4 x, int4 n) } } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int8 shl(int8 x, int8 n) { @@ -1647,28 +1655,28 @@ public static int8 shl(int8 x, int8 n) } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint2 shl(uint2 x, uint2 n) { return (uint2)shl((int2)x, (int2)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint3 shl(uint3 x, uint3 n) { return (uint3)shl((int3)x, (int3)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint4 shl(uint4 x, uint4 n) { return (uint4)shl((int4)x, (int4)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint8 shl(uint8 x, uint8 n) { @@ -1676,28 +1684,28 @@ public static uint8 shl(uint8 x, uint8 n) } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint2 shl(uint2 x, int2 n) { return shl(x, (uint2)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint3 shl(uint3 x, int3 n) { return shl(x, (uint3)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint4 shl(uint4 x, int4 n) { return shl(x, (uint4)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint8 shl(uint8 x, int8 n) { @@ -1705,7 +1713,7 @@ public static uint8 shl(uint8 x, int8 n) } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long2 shl(long2 x, long2 n) { @@ -1719,7 +1727,7 @@ public static long2 shl(long2 x, long2 n) } } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long3 shl(long3 x, long3 n) { @@ -1733,7 +1741,7 @@ public static long3 shl(long3 x, long3 n) } } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long4 shl(long4 x, long4 n) { @@ -1748,21 +1756,21 @@ public static long4 shl(long4 x, long4 n) } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong2 shl(ulong2 x, ulong2 n) { return (ulong2)shl((long2)x, (long2)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong3 shl(ulong3 x, ulong3 n) { return (ulong3)shl((long3)x, (long3)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong4 shl(ulong4 x, ulong4 n) { @@ -1770,21 +1778,21 @@ public static ulong4 shl(ulong4 x, ulong4 n) } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong2 shl(ulong2 x, long2 n) { return shl(x, (ulong2)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong3 shl(ulong3 x, long3 n) { return shl(x, (ulong3)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong4 shl(ulong4 x, long4 n) { @@ -1792,42 +1800,42 @@ public static ulong4 shl(ulong4 x, long4 n) } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte2 shrl(sbyte2 x, sbyte2 n) { return (sbyte2)shrl((byte2)x, (byte2)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte3 shrl(sbyte3 x, sbyte3 n) { return (sbyte3)shrl((byte3)x, (byte3)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the byteerval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the byteerval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte4 shrl(sbyte4 x, sbyte4 n) { return (sbyte4)shrl((byte4)x, (byte4)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the byteerval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the byteerval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte8 shrl(sbyte8 x, sbyte8 n) { return (sbyte8)shrl((byte8)x, (byte8)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte16 shrl(sbyte16 x, sbyte16 n) { return (sbyte16)shrl((byte16)x, (byte16)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte32 shrl(sbyte32 x, sbyte32 n) { @@ -1835,7 +1843,7 @@ public static sbyte32 shrl(sbyte32 x, sbyte32 n) } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte2 shrl(byte2 x, byte2 n) { @@ -1849,7 +1857,7 @@ public static byte2 shrl(byte2 x, byte2 n) } } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte3 shrl(byte3 x, byte3 n) { @@ -1863,7 +1871,7 @@ public static byte3 shrl(byte3 x, byte3 n) } } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte4 shrl(byte4 x, byte4 n) { @@ -1877,7 +1885,7 @@ public static byte4 shrl(byte4 x, byte4 n) } } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte8 shrl(byte8 x, byte8 n) { @@ -1891,7 +1899,7 @@ public static byte8 shrl(byte8 x, byte8 n) } } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte16 shrl(byte16 x, byte16 n) { @@ -1905,7 +1913,7 @@ public static byte16 shrl(byte16 x, byte16 n) } } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte32 shrl(byte32 x, byte32 n) { @@ -1919,42 +1927,42 @@ public static byte32 shrl(byte32 x, byte32 n) } } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte2 shrl(byte2 x, sbyte2 n) { return shrl(x, (byte2)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte3 shrl(byte3 x, sbyte3 n) { return shrl(x, (byte3)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte4 shrl(byte4 x, sbyte4 n) { return shrl(x, (byte4)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte8 shrl(byte8 x, sbyte8 n) { return shrl(x, (byte8)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte16 shrl(byte16 x, sbyte16 n) { return shrl(x, (byte16)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte32 shrl(byte32 x, sbyte32 n) { @@ -1962,7 +1970,7 @@ public static byte32 shrl(byte32 x, sbyte32 n) } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short2 shrl(short2 x, short2 n) { @@ -1976,7 +1984,7 @@ public static short2 shrl(short2 x, short2 n) } } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short3 shrl(short3 x, short3 n) { @@ -1990,7 +1998,7 @@ public static short3 shrl(short3 x, short3 n) } } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short4 shrl(short4 x, short4 n) { @@ -2004,7 +2012,7 @@ public static short4 shrl(short4 x, short4 n) } } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short8 shrl(short8 x, short8 n) { @@ -2018,7 +2026,7 @@ public static short8 shrl(short8 x, short8 n) } } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short16 shrl(short16 x, short16 n) { @@ -2033,76 +2041,76 @@ public static short16 shrl(short16 x, short16 n) } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort2 shrl(ushort2 x, ushort2 n) { return (ushort2)shrl((short2)x, (short2)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort3 shrl(ushort3 x, ushort3 n) { return (ushort3)shrl((short3)x, (short3)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort4 shrl(ushort4 x, ushort4 n) { return (ushort4)shrl((short4)x, (short4)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort8 shrl(ushort8 x, ushort8 n) { return (ushort8)shrl((short8)x, (short8)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the uinterval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort16 shrl(ushort16 x, ushort16 n) { return (ushort16)shrl((short16)x, (short16)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort3 shrl(ushort3 x, short3 n) { return shrl(x, (ushort3)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort4 shrl(ushort4 x, short4 n) { return shrl(x, (ushort4)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort8 shrl(ushort8 x, short8 n) { return shrl(x, (ushort8)n); } - /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort16 shrl(ushort16 x, short16 n) { return shrl(x, (ushort16)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int2 shrl(int2 x, int2 n) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.srlv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n))); + return RegisterConversion.ToInt2(Xse.srlv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n))); } else { @@ -2110,13 +2118,13 @@ public static int2 shrl(int2 x, int2 n) } } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int3 shrl(int3 x, int3 n) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.srlv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n))); + return RegisterConversion.ToInt3(Xse.srlv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n))); } else { @@ -2124,13 +2132,13 @@ public static int3 shrl(int3 x, int3 n) } } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int4 shrl(int4 x, int4 n) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.srlv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n))); + return RegisterConversion.ToInt4(Xse.srlv_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n))); } else { @@ -2138,7 +2146,7 @@ public static int4 shrl(int4 x, int4 n) } } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int8 shrl(int8 x, int8 n) { @@ -2153,28 +2161,28 @@ public static int8 shrl(int8 x, int8 n) } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint2 shrl(uint2 x, uint2 n) { return (uint2)shrl((int2)x, (int2)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint3 shrl(uint3 x, uint3 n) { return (uint3)shrl((int3)x, (int3)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint4 shrl(uint4 x, uint4 n) { return (uint4)shrl((int4)x, (int4)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint8 shrl(uint8 x, uint8 n) { @@ -2182,28 +2190,28 @@ public static uint8 shrl(uint8 x, uint8 n) } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint2 shrl(uint2 x, int2 n) { return shrl(x, (uint2)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint3 shrl(uint3 x, int3 n) { return shrl(x, (uint3)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint4 shrl(uint4 x, int4 n) { return shrl(x, (uint4)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint8 shrl(uint8 x, int8 n) { @@ -2211,7 +2219,7 @@ public static uint8 shrl(uint8 x, int8 n) } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long2 shrl(long2 x, long2 n) { @@ -2225,7 +2233,7 @@ public static long2 shrl(long2 x, long2 n) } } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long3 shrl(long3 x, long3 n) { @@ -2239,7 +2247,7 @@ public static long3 shrl(long3 x, long3 n) } } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long4 shrl(long4 x, long4 n) { @@ -2254,21 +2262,21 @@ public static long4 shrl(long4 x, long4 n) } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong2 shrl(ulong2 x, ulong2 n) { return (ulong2)shrl((long2)x, (long2)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong3 shrl(ulong3 x, ulong3 n) { return (ulong3)shrl((long3)x, (long3)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong4 shrl(ulong4 x, ulong4 n) { @@ -2276,21 +2284,21 @@ public static ulong4 shrl(ulong4 x, ulong4 n) } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong2 shrl(ulong2 x, long2 n) { return shrl(x, (ulong2)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong3 shrl(ulong3 x, long3 n) { return shrl(x, (ulong3)n); } - /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (unsigned) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong4 shrl(ulong4 x, long4 n) { @@ -2298,7 +2306,7 @@ public static ulong4 shrl(ulong4 x, long4 n) } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte2 shra(sbyte2 x, sbyte2 n) { @@ -2312,7 +2320,7 @@ public static sbyte2 shra(sbyte2 x, sbyte2 n) } } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte3 shra(sbyte3 x, sbyte3 n) { @@ -2326,7 +2334,7 @@ public static sbyte3 shra(sbyte3 x, sbyte3 n) } } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte4 shra(sbyte4 x, sbyte4 n) { @@ -2340,7 +2348,7 @@ public static sbyte4 shra(sbyte4 x, sbyte4 n) } } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte8 shra(sbyte8 x, sbyte8 n) { @@ -2354,7 +2362,7 @@ public static sbyte8 shra(sbyte8 x, sbyte8 n) } } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte16 shra(sbyte16 x, sbyte16 n) { @@ -2368,7 +2376,7 @@ public static sbyte16 shra(sbyte16 x, sbyte16 n) } } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 7] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte32 shra(sbyte32 x, sbyte32 n) { @@ -2383,7 +2391,7 @@ public static sbyte32 shra(sbyte32 x, sbyte32 n) } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short2 shra(short2 x, short2 n) { @@ -2397,7 +2405,7 @@ public static short2 shra(short2 x, short2 n) } } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short3 shra(short3 x, short3 n) { @@ -2411,7 +2419,7 @@ public static short3 shra(short3 x, short3 n) } } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short4 shra(short4 x, short4 n) { @@ -2425,7 +2433,7 @@ public static short4 shra(short4 x, short4 n) } } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short8 shra(short8 x, short8 n) { @@ -2439,7 +2447,7 @@ public static short8 shra(short8 x, short8 n) } } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 15] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short16 shra(short16 x, short16 n) { @@ -2454,13 +2462,13 @@ public static short16 shra(short16 x, short16 n) } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int2 shra(int2 x, int2 n) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.srav_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), 2)); + return RegisterConversion.ToInt2(Xse.srav_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), 2)); } else { @@ -2468,13 +2476,13 @@ public static int2 shra(int2 x, int2 n) } } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int3 shra(int3 x, int3 n) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.srav_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), 3)); + return RegisterConversion.ToInt3(Xse.srav_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), 3)); } else { @@ -2482,13 +2490,13 @@ public static int3 shra(int3 x, int3 n) } } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int4 shra(int4 x, int4 n) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.srav_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), 4)); + return RegisterConversion.ToInt4(Xse.srav_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(n), 4)); } else { @@ -2496,7 +2504,7 @@ public static int4 shra(int4 x, int4 n) } } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 31] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int8 shra(int8 x, int8 n) { @@ -2511,7 +2519,7 @@ public static int8 shra(int8 x, int8 n) } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long2 shra(long2 x, long2 n) { @@ -2525,7 +2533,7 @@ public static long2 shra(long2 x, long2 n) } } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long3 shra(long3 x, long3 n) { @@ -2539,7 +2547,7 @@ public static long3 shra(long3 x, long3 n) } } - /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior and yields different results when compiling managed C#, for SSE or for AVX. + /// Returns (signed) for each corresponding component. Shifting by a value outside of the interval [0, 63] is undefined behavior. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long4 shra(long4 x, long4 n) { diff --git a/Runtime/Math Lib/Functions/Comparison/Boolean Vector Evaluation/All.cs b/Runtime/Math Lib/Functions/Comparison/Boolean Vector Evaluation/All.cs index c405eb8..24f31c7 100644 --- a/Runtime/Math Lib/Functions/Comparison/Boolean Vector Evaluation/All.cs +++ b/Runtime/Math Lib/Functions/Comparison/Boolean Vector Evaluation/All.cs @@ -131,7 +131,7 @@ public static bool all(byte2 x) { if (Sse2.IsSse2Supported) { - return 0 == Sse2.extract_epi16(Sse2.cmpeq_epi8(x, Sse2.setzero_si128()), 0); + return 0 == Xse.extract_epi16(Sse2.cmpeq_epi8(x, Sse2.setzero_si128()), 0); } else { diff --git a/Runtime/Math Lib/Functions/Comparison/Boolean Vector Evaluation/Any.cs b/Runtime/Math Lib/Functions/Comparison/Boolean Vector Evaluation/Any.cs index b673a17..9381fb4 100644 --- a/Runtime/Math Lib/Functions/Comparison/Boolean Vector Evaluation/Any.cs +++ b/Runtime/Math Lib/Functions/Comparison/Boolean Vector Evaluation/Any.cs @@ -131,7 +131,7 @@ public static bool any(byte2 x) { if (Sse2.IsSse2Supported) { - return 0 != Sse2.extract_epi16(x, 0); + return 0 != Xse.extract_epi16(x, 0); } else { diff --git a/Runtime/Math Lib/Functions/Comparison/Boolean Vector Evaluation/Count.cs b/Runtime/Math Lib/Functions/Comparison/Boolean Vector Evaluation/Count.cs index d64d7f9..800d5fd 100644 --- a/Runtime/Math Lib/Functions/Comparison/Boolean Vector Evaluation/Count.cs +++ b/Runtime/Math Lib/Functions/Comparison/Boolean Vector Evaluation/Count.cs @@ -11,7 +11,7 @@ namespace MaxMath { unsafe public static partial class maxmath { - /// Returns the number of s in a . + /// Returns the number of values in a . [return: AssumeRange(0ul, 2ul)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint count(bool2 x) @@ -22,7 +22,7 @@ public static uint count(bool2 x) return (uint)math.countbits((uint)(*(ushort*)&x)); } - /// Returns the number of s in a . + /// Returns the number of values in a . [return: AssumeRange(0ul, 3ul)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint count(bool3 x) @@ -37,7 +37,7 @@ public static uint count(bool3 x) return (uint)math.countbits(toInt); } - /// Returns the number of s in a . + /// Returns the number of values in a . [return: AssumeRange(0ul, 4ul)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint count(bool4 x) @@ -50,7 +50,7 @@ public static uint count(bool4 x) return (uint)math.countbits(*(int*)&x); } - /// Returns the number of s in a . + /// Returns the number of values in a . [return: AssumeRange(0ul, 8ul)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint count(bool8 x) @@ -74,7 +74,7 @@ public static uint count(bool8 x) } } - /// Returns the number of s in a . + /// Returns the number of values in a . [return: AssumeRange(0ul, 16ul)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint count(bool16 x) @@ -106,7 +106,7 @@ public static uint count(bool16 x) } } - /// Returns the number of s in a . + /// Returns the number of values in a . [return: AssumeRange(0ul, 32ul)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint count(bool32 x) diff --git a/Runtime/Math Lib/Functions/Comparison/Boolean Vector Evaluation/First.cs b/Runtime/Math Lib/Functions/Comparison/Boolean Vector Evaluation/First.cs index aacb0fe..b1b3598 100644 --- a/Runtime/Math Lib/Functions/Comparison/Boolean Vector Evaluation/First.cs +++ b/Runtime/Math Lib/Functions/Comparison/Boolean Vector Evaluation/First.cs @@ -11,7 +11,7 @@ namespace MaxMath { unsafe public static partial class maxmath { - /// Returns the index of the first of a or 4 if none are . + /// Returns the index of the first value of a or 4 if none are . [return: AssumeRange(0, 4)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int first(bool2 x) @@ -22,7 +22,7 @@ public static int first(bool2 x) return (int)((uint)math.tzcnt((uint)*(ushort*)&x) / 8); } - /// Returns the index of the first of a or 4 if none are . + /// Returns the index of the first value of a or 4 if none are . [return: AssumeRange(0, 4)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int first(bool3 x) @@ -37,7 +37,7 @@ public static int first(bool3 x) return (int)((uint)math.tzcnt(toInt) / 8); } - /// Returns the index of the first of a or 4 if none are . + /// Returns the index of the first value of a or 4 if none are . [return: AssumeRange(0, 4)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int first(bool4 x) @@ -50,7 +50,7 @@ public static int first(bool4 x) return (int)((uint)math.tzcnt(*(int*)&x) / 8); } - /// Returns the index of the first of a or 8 if none are . + /// Returns the index of the first value of a or 8 if none are . [return: AssumeRange(0, 8)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int first(bool8 x) @@ -74,7 +74,7 @@ public static int first(bool8 x) } } - /// Returns the index of the first of a or 32 if none are . + /// Returns the index of the first value of a or 32 if none are . [return: AssumeRange(0, 32)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int first(bool16 x) @@ -117,7 +117,7 @@ public static int first(bool16 x) } } - /// Returns the index of the first of a or 32 if none are . + /// Returns the index of the first value of a or 32 if none are . [return: AssumeRange(0, 32)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int first(bool32 x) diff --git a/Runtime/Math Lib/Functions/Comparison/CompareTo.cs b/Runtime/Math Lib/Functions/Comparison/CompareTo.cs index a5440af..ff980fc 100644 --- a/Runtime/Math Lib/Functions/Comparison/CompareTo.cs +++ b/Runtime/Math Lib/Functions/Comparison/CompareTo.cs @@ -8,6 +8,248 @@ namespace MaxMath { + namespace Intrinsics + { + unsafe public static partial class Xse + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmp_epu8(v128 a, v128 b, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + return Sse2.sub_epi8(cmpge_epu8(b, a, elements), cmpge_epu8(a, b, elements)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_cmp_epu8(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + return Avx2.mm256_sub_epi8(mm256_cmpge_epu8(b, a), mm256_cmpge_epu8(a, b)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmp_epi8(v128 a, v128 b) + { + if (Sse2.IsSse2Supported) + { + return Sse2.sub_epi8(Sse2.cmpgt_epi8(b, a), Sse2.cmpgt_epi8(a, b)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_cmp_epi8(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + return Avx2.mm256_sub_epi8(Avx2.mm256_cmpgt_epi8(b, a), Avx2.mm256_cmpgt_epi8(a, b)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmp_epu16(v128 a, v128 b, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + return Sse2.sub_epi16(cmpge_epu16(b, a, elements), cmpge_epu16(a, b, elements)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_cmp_epu16(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + return Avx2.mm256_sub_epi16(mm256_cmpge_epu16(b, a), mm256_cmpge_epu16(a, b)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmp_epi16(v128 a, v128 b) + { + if (Sse2.IsSse2Supported) + { + return Sse2.sub_epi16(Sse2.cmpgt_epi16(b, a), Sse2.cmpgt_epi16(a, b)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_cmp_epi16(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + return Avx2.mm256_sub_epi16(Avx2.mm256_cmpgt_epi16(b, a), Avx2.mm256_cmpgt_epi16(a, b)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmp_epu32(v128 a, v128 b, byte elements = 4) + { + if (Sse4_1.IsSse41Supported) + { + return Sse2.sub_epi32(cmpge_epu32(b, a, elements), cmpge_epu32(a, b, elements)); + } + else if (Sse2.IsSse2Supported) + { + return Sse2.sub_epi32(cmpgt_epu32(b, a, elements), cmpgt_epu32(a, b, elements)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_cmp_epu32(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + return Avx2.mm256_sub_epi32(mm256_cmpge_epu32(b, a), mm256_cmpge_epu32(a, b)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmp_epi32(v128 a, v128 b) + { + if (Sse2.IsSse2Supported) + { + return Sse2.sub_epi32(Sse2.cmpgt_epi32(b, a), Sse2.cmpgt_epi32(a, b)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_cmp_epi32(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + return Avx2.mm256_sub_epi32(Avx2.mm256_cmpgt_epi32(b, a), Avx2.mm256_cmpgt_epi32(a, b)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmp_epu64(v128 a, v128 b) + { + if (Sse2.IsSse2Supported) + { + return Sse2.sub_epi64(cmpgt_epu64(b, a), cmpgt_epu64(a, b)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_cmp_epu64(v256 a, v256 b, byte elements = 4) + { + if (Avx2.IsAvx2Supported) + { + return Avx2.mm256_sub_epi64(mm256_cmpgt_epu64(b, a, elements), mm256_cmpgt_epu64(a, b, elements)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmp_epi64(v128 a, v128 b) + { + if (Sse2.IsSse2Supported) + { + return Sse2.sub_epi64(cmpgt_epi64(b, a), cmpgt_epi64(a, b)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_cmp_epi64(v256 a, v256 b, byte elements = 4) + { + if (Avx2.IsAvx2Supported) + { + return Avx2.mm256_sub_epi64(mm256_cmpgt_epi64(b, a, elements), mm256_cmpgt_epi64(a, b, elements)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmp_pq(v128 a, v128 b, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + return Sse2.sub_epi8(quarter.Vectorized.cmpgt_pq(b, a, elements: elements), quarter.Vectorized.cmpgt_pq(a, b, elements: elements)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmp_ph(v128 a, v128 b, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + return Sse2.sub_epi16(cmpgt_ph(b, a, elements: elements), cmpgt_ph(a, b, elements: elements)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmp_ps(v128 a, v128 b) + { + if (Sse2.IsSse2Supported) + { + return Sse2.sub_epi32(Sse.cmpgt_ps(b, a), Sse.cmpgt_ps(a, b)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_cmp_ps(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + return Avx2.mm256_sub_epi32(Avx.mm256_cmp_ps(b, a, (int)Avx.CMP.GT_OQ), Avx.mm256_cmp_ps(a, b, (int)Avx.CMP.GT_OQ)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmp_pd(v128 a, v128 b) + { + if (Sse2.IsSse2Supported) + { + return Sse2.sub_epi64(Sse2.cmpgt_pd(b, a), Sse2.cmpgt_pd(a, b)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_cmp_pd(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + return Avx2.mm256_sub_epi64(Avx.mm256_cmp_pd(b, a, (int)Avx.CMP.GT_OQ), Avx.mm256_cmp_pd(a, b, (int)Avx.CMP.GT_OQ)); + } + else throw new IllegalInstructionException(); + } + } + } + + unsafe public static partial class maxmath { /// Returns -1 if is smaller than , 1 if is greater than or 0 if both are equal. @@ -117,6 +359,22 @@ public static int compareto(ulong x, ulong y) } + /// Returns -1 if is smaller than , 1 if is greater than or 0 if both are equal. + [return: AssumeRange(-1, 1)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int compareto(quarter x, quarter y) + { + return tobyte(x > y) - tobyte(x < y); + } + + /// Returns -1 if is smaller than , 1 if is greater than or 0 if both are equal. + [return: AssumeRange(-1, 1)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int compareto(half x, half y) + { + return tobyte(x.IsGreaterThan(y)) - tobyte(x.IsLessThan(y)); + } + /// Returns -1 if is smaller than , 1 if is greater than or 0 if both are equal. [return: AssumeRange(-1, 1)] [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -140,7 +398,7 @@ public static sbyte2 compareto(sbyte2 x, sbyte2 y) { if (Sse2.IsSse2Supported) { - return Sse2.sub_epi8(Sse2.cmpgt_epi8(y, x), Sse2.cmpgt_epi8(x, y)); + return Xse.cmp_epi8(x, y); } else { @@ -155,7 +413,7 @@ public static sbyte3 compareto(sbyte3 x, sbyte3 y) { if (Sse2.IsSse2Supported) { - return Sse2.sub_epi8(Sse2.cmpgt_epi8(y, x), Sse2.cmpgt_epi8(x, y)); + return Xse.cmp_epi8(x, y); } else { @@ -171,7 +429,7 @@ public static sbyte4 compareto(sbyte4 x, sbyte4 y) { if (Sse2.IsSse2Supported) { - return Sse2.sub_epi8(Sse2.cmpgt_epi8(y, x), Sse2.cmpgt_epi8(x, y)); + return Xse.cmp_epi8(x, y); } else { @@ -188,7 +446,7 @@ public static sbyte8 compareto(sbyte8 x, sbyte8 y) { if (Sse2.IsSse2Supported) { - return Sse2.sub_epi8(Sse2.cmpgt_epi8(y, x), Sse2.cmpgt_epi8(x, y)); + return Xse.cmp_epi8(x, y); } else { @@ -209,7 +467,7 @@ public static sbyte16 compareto(sbyte16 x, sbyte16 y) { if (Sse2.IsSse2Supported) { - return Sse2.sub_epi8(Sse2.cmpgt_epi8(y, x), Sse2.cmpgt_epi8(x, y)); + return Xse.cmp_epi8(x, y); } else { @@ -238,7 +496,7 @@ public static sbyte32 compareto(sbyte32 x, sbyte32 y) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_sub_epi8(Avx2.mm256_cmpgt_epi8(y, x), Avx2.mm256_cmpgt_epi8(x, y)); + return Xse.mm256_cmp_epi8(x, y); } else { @@ -254,7 +512,7 @@ public static sbyte2 compareto(byte2 x, byte2 y) { if (Sse2.IsSse2Supported) { - return Sse2.sub_epi8(Xse.cmpge_epu8(y, x, 2), Xse.cmpge_epu8(x, y, 2)); + return Xse.cmp_epu8(x, y, 2); } else { @@ -269,7 +527,7 @@ public static sbyte3 compareto(byte3 x, byte3 y) { if (Sse2.IsSse2Supported) { - return Sse2.sub_epi8(Xse.cmpge_epu8(y, x, 3), Xse.cmpge_epu8(x, y, 3)); + return Xse.cmp_epu8(x, y, 3); } else { @@ -285,7 +543,7 @@ public static sbyte4 compareto(byte4 x, byte4 y) { if (Sse2.IsSse2Supported) { - return Sse2.sub_epi8(Xse.cmpge_epu8(y, x, 4), Xse.cmpge_epu8(x, y, 4)); + return Xse.cmp_epu8(x, y, 4); } else { @@ -302,7 +560,7 @@ public static sbyte8 compareto(byte8 x, byte8 y) { if (Sse2.IsSse2Supported) { - return Sse2.sub_epi8(Xse.cmpge_epu8(y, x, 8), Xse.cmpge_epu8(x, y, 8)); + return Xse.cmp_epu8(x, y, 8); } else { @@ -323,7 +581,7 @@ public static sbyte16 compareto(byte16 x, byte16 y) { if (Sse2.IsSse2Supported) { - return Sse2.sub_epi8(Xse.cmpge_epu8(y, x, 16), Xse.cmpge_epu8(x, y, 16)); + return Xse.cmp_epu8(x, y, 16); } else { @@ -352,7 +610,7 @@ public static sbyte32 compareto(byte32 x, byte32 y) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_sub_epi8(Xse.mm256_cmpge_epu8(y, x), Xse.mm256_cmpge_epu8(x, y)); + return Xse.mm256_cmp_epu8(x, y); } else { @@ -368,7 +626,7 @@ public static short2 compareto(short2 x, short2 y) { if (Sse2.IsSse2Supported) { - return Sse2.sub_epi16(Sse2.cmpgt_epi16(y, x), Sse2.cmpgt_epi16(x, y)); + return Xse.cmp_epi16(x, y); } else { @@ -383,7 +641,7 @@ public static short3 compareto(short3 x, short3 y) { if (Sse2.IsSse2Supported) { - return Sse2.sub_epi16(Sse2.cmpgt_epi16(y, x), Sse2.cmpgt_epi16(x, y)); + return Xse.cmp_epi16(x, y); } else { @@ -399,7 +657,7 @@ public static short4 compareto(short4 x, short4 y) { if (Sse2.IsSse2Supported) { - return Sse2.sub_epi16(Sse2.cmpgt_epi16(y, x), Sse2.cmpgt_epi16(x, y)); + return Xse.cmp_epi16(x, y); } else { @@ -416,7 +674,7 @@ public static short8 compareto(short8 x, short8 y) { if (Sse2.IsSse2Supported) { - return Sse2.sub_epi16(Sse2.cmpgt_epi16(y, x), Sse2.cmpgt_epi16(x, y)); + return Xse.cmp_epi16(x, y); } else { @@ -437,7 +695,7 @@ public static short16 compareto(short16 x, short16 y) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_sub_epi16(Avx2.mm256_cmpgt_epi16(y, x), Avx2.mm256_cmpgt_epi16(x, y)); + return Xse.mm256_cmp_epi16(x, y); } else { @@ -453,13 +711,7 @@ public static short2 compareto(ushort2 x, ushort2 y) { if (Sse2.IsSse2Supported) { - if (Sse4_1.IsSse41Supported && !(Xse.constexpr.ALL_LE_EPU16(x, (ushort)short.MaxValue, 2) && Xse.constexpr.ALL_LE_EPU16(y, (ushort)short.MaxValue, 2))) - { - return Sse2.sub_epi16(Xse.cmpge_epu16(y, x, 2), Xse.cmpge_epu16(x, y, 2)); - } - - - return Sse2.sub_epi16(Xse.cmpgt_epu16(y, x, 2), Xse.cmpgt_epu16(x, y, 2)); + return Xse.cmp_epu16(x, y, 2); } else { @@ -474,12 +726,7 @@ public static short3 compareto(ushort3 x, ushort3 y) { if (Sse2.IsSse2Supported) { - if (Sse4_1.IsSse41Supported && !(Xse.constexpr.ALL_LE_EPU16(x, (ushort)short.MaxValue, 3) && Xse.constexpr.ALL_LE_EPU16(y, (ushort)short.MaxValue, 3))) - { - return Sse2.sub_epi16(Xse.cmpge_epu16(y, x, 3), Xse.cmpge_epu16(x, y, 3)); - } - - return Sse2.sub_epi16(Xse.cmpgt_epu16(y, x, 3), Xse.cmpgt_epu16(x, y, 3)); + return Xse.cmp_epu16(x, y, 3); } else { @@ -495,12 +742,7 @@ public static short4 compareto(ushort4 x, ushort4 y) { if (Sse2.IsSse2Supported) { - if (Sse4_1.IsSse41Supported && !(Xse.constexpr.ALL_LE_EPU16(x, (ushort)short.MaxValue, 4) && Xse.constexpr.ALL_LE_EPU16(y, (ushort)short.MaxValue, 4))) - { - return Sse2.sub_epi16(Xse.cmpge_epu16(y, x, 4), Xse.cmpge_epu16(x, y, 4)); - } - - return Sse2.sub_epi16(Xse.cmpgt_epu16(y, x, 4), Xse.cmpgt_epu16(x, y, 4)); + return Xse.cmp_epu16(x, y, 4); } else { @@ -517,12 +759,7 @@ public static short8 compareto(ushort8 x, ushort8 y) { if (Sse2.IsSse2Supported) { - if (Sse4_1.IsSse41Supported && !(Xse.constexpr.ALL_LE_EPU16(x, (ushort)short.MaxValue, 8) && Xse.constexpr.ALL_LE_EPU16(y, (ushort)short.MaxValue, 8))) - { - return Sse2.sub_epi16(Xse.cmpge_epu16(y, x, 8), Xse.cmpge_epu16(x, y, 8)); - } - - return Sse2.sub_epi16(Xse.cmpgt_epu16(y, x, 8), Xse.cmpgt_epu16(x, y, 8)); + return Xse.cmp_epu16(x, y, 8); } else { @@ -543,7 +780,7 @@ public static short16 compareto(ushort16 x, ushort16 y) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_sub_epi16(Xse.mm256_cmpge_epu16(y, x), Xse.mm256_cmpge_epu16(x, y)); + return Xse.mm256_cmp_epu16(x, y); } else { @@ -559,10 +796,7 @@ public static int2 compareto(int2 x, int2 y) { if (Sse2.IsSse2Supported) { - v128 _x = RegisterConversion.ToV128(x); - v128 _y = RegisterConversion.ToV128(y); - - return RegisterConversion.ToType(Sse2.sub_epi32(Sse2.cmpgt_epi32(_y, _x), Sse2.cmpgt_epi32(_x, _y))); + return RegisterConversion.ToInt2(Xse.cmp_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); } else { @@ -577,10 +811,7 @@ public static int3 compareto(int3 x, int3 y) { if (Sse2.IsSse2Supported) { - v128 _x = RegisterConversion.ToV128(x); - v128 _y = RegisterConversion.ToV128(y); - - return RegisterConversion.ToType(Sse2.sub_epi32(Sse2.cmpgt_epi32(_y, _x), Sse2.cmpgt_epi32(_x, _y))); + return RegisterConversion.ToInt3(Xse.cmp_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); } else { @@ -596,10 +827,7 @@ public static int4 compareto(int4 x, int4 y) { if (Sse2.IsSse2Supported) { - v128 _x = RegisterConversion.ToV128(x); - v128 _y = RegisterConversion.ToV128(y); - - return RegisterConversion.ToType(Sse2.sub_epi32(Sse2.cmpgt_epi32(_y, _x), Sse2.cmpgt_epi32(_x, _y))); + return RegisterConversion.ToInt4(Xse.cmp_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); } else { @@ -616,7 +844,7 @@ public static int8 compareto(int8 x, int8 y) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_sub_epi32(Avx2.mm256_cmpgt_epi32(y, x), Avx2.mm256_cmpgt_epi32(x, y)); + return Xse.mm256_cmp_epi32(x, y); } else { @@ -630,19 +858,9 @@ public static int8 compareto(int8 x, int8 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int2 compareto(uint2 x, uint2 y) { - if (Sse4_1.IsSse41Supported) - { - v128 _x = RegisterConversion.ToV128(x); - v128 _y = RegisterConversion.ToV128(y); - - return RegisterConversion.ToType(Sse2.sub_epi32(Sse2.cmpeq_epi32(Sse4_1.max_epu32(_y, _x), _y), Sse2.cmpeq_epi32(Sse4_1.max_epu32(_x, _y), _x)));; - } - else if (Sse2.IsSse2Supported) + if (Sse2.IsSse2Supported) { - v128 _x = RegisterConversion.ToV128(x); - v128 _y = RegisterConversion.ToV128(y); - - return RegisterConversion.ToType(Sse2.sub_epi32(Xse.cmpgt_epu32(_y, _x, 2), Xse.cmpgt_epu32(_x, _y, 2))); + return RegisterConversion.ToInt2(Xse.cmp_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 2)); } else { @@ -655,19 +873,9 @@ public static int2 compareto(uint2 x, uint2 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int3 compareto(uint3 x, uint3 y) { - if (Sse4_1.IsSse41Supported) - { - v128 _x = RegisterConversion.ToV128(x); - v128 _y = RegisterConversion.ToV128(y); - - return RegisterConversion.ToType(Sse2.sub_epi32(Sse2.cmpeq_epi32(Sse4_1.max_epu32(_y, _x), _y), Sse2.cmpeq_epi32(Sse4_1.max_epu32(_x, _y), _x))); - } - else if (Sse2.IsSse2Supported) + if (Sse2.IsSse2Supported) { - v128 _x = RegisterConversion.ToV128(x); - v128 _y = RegisterConversion.ToV128(y); - - return RegisterConversion.ToType(Sse2.sub_epi32(Xse.cmpgt_epu32(_y, _x, 3), Xse.cmpgt_epu32(_x, _y, 3))); + return RegisterConversion.ToInt3(Xse.cmp_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 3)); } else { @@ -681,19 +889,9 @@ public static int3 compareto(uint3 x, uint3 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int4 compareto(uint4 x, uint4 y) { - if (Sse4_1.IsSse41Supported) - { - v128 _x = RegisterConversion.ToV128(x); - v128 _y = RegisterConversion.ToV128(y); - - return RegisterConversion.ToType(Sse2.sub_epi32(Sse2.cmpeq_epi32(Sse4_1.max_epu32(_y, _x), _y), Sse2.cmpeq_epi32(Sse4_1.max_epu32(_x, _y), _x))); - } - else if (Sse2.IsSse2Supported) + if (Sse2.IsSse2Supported) { - v128 _x = RegisterConversion.ToV128(x); - v128 _y = RegisterConversion.ToV128(y); - - return RegisterConversion.ToType(Sse2.sub_epi32(Xse.cmpgt_epu32(_y, _x, 4), Xse.cmpgt_epu32(_x, _y, 4))); + return RegisterConversion.ToInt4(Xse.cmp_epu32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 4)); } else { @@ -710,7 +908,7 @@ public static int8 compareto(uint8 x, uint8 y) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_sub_epi32(Xse.mm256_cmpge_epu32(y, x), Xse.mm256_cmpge_epu32(x, y)); + return Xse.mm256_cmp_epu32(x, y); } else { @@ -724,9 +922,9 @@ public static int8 compareto(uint8 x, uint8 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long2 compareto(long2 x, long2 y) { - if (Sse4_1.IsSse41Supported) + if (Sse2.IsSse2Supported) { - return Sse2.sub_epi64(Xse.cmpgt_epi64(y, x), Xse.cmpgt_epi64(x, y)); + return Xse.cmp_epi64(x, y); } else { @@ -741,7 +939,7 @@ public static long3 compareto(long3 x, long3 y) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_sub_epi64(Xse.mm256_cmpgt_epi64(y, x, 3), Xse.mm256_cmpgt_epi64(x, y, 3)); + return Xse.mm256_cmp_epi64(x, y, 3); } else { @@ -756,7 +954,7 @@ public static long4 compareto(long4 x, long4 y) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_sub_epi64(Xse.mm256_cmpgt_epi64(y, x, 4), Xse.mm256_cmpgt_epi64(x, y, 4)); + return Xse.mm256_cmp_epi64(x, y, 4); } else { @@ -772,7 +970,7 @@ public static long2 compareto(ulong2 x, ulong2 y) { if (Sse2.IsSse2Supported) { - return Sse2.sub_epi64(Xse.cmpgt_epu64(y, x), Xse.cmpgt_epu64(x, y)); + return Xse.cmp_epu64(x, y); } else { @@ -787,7 +985,7 @@ public static long3 compareto(ulong3 x, ulong3 y) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_sub_epi64(Xse.mm256_cmpgt_epu64(y, x), Xse.mm256_cmpgt_epu64(x, y)); + return Xse.mm256_cmp_epu64(x, y, 3); } else { @@ -802,7 +1000,7 @@ public static long4 compareto(ulong4 x, ulong4 y) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_sub_epi64(Xse.mm256_cmpgt_epu64(y, x), Xse.mm256_cmpgt_epu64(x, y)); + return Xse.mm256_cmp_epu64(x, y, 4); } else { @@ -812,16 +1010,153 @@ public static long4 compareto(ulong4 x, ulong4 y) } + /// Returns an with each element set to -1 if the corresponding value in is smaller than the corresponding value in , 1 if the corresponding value in is greater than the corresponding value in or 0 if both are equal. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte2 compareto(quarter2 x, quarter2 y) + { + if (Sse2.IsSse2Supported) + { + return Xse.cmp_pq(x, y, 2); + } + else + { + return new sbyte2((sbyte)compareto(x.x, y.x), + (sbyte)compareto(x.y, y.y)); + } + } + + /// Returns an with each element set to -1 if the corresponding value in is smaller than the corresponding value in , 1 if the corresponding value in is greater than the corresponding value in or 0 if both are equal. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte3 compareto(quarter3 x, quarter3 y) + { + if (Sse2.IsSse2Supported) + { + return Xse.cmp_pq(x, y, 3); + } + else + { + return new sbyte3((sbyte)compareto(x.x, y.x), + (sbyte)compareto(x.y, y.y), + (sbyte)compareto(x.z, y.z)); + } + } + + /// Returns an with each element set to -1 if the corresponding value in is smaller than the corresponding value in , 1 if the corresponding value in is greater than the corresponding value in or 0 if both are equal. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte4 compareto(quarter4 x, quarter4 y) + { + if (Sse2.IsSse2Supported) + { + return Xse.cmp_pq(x, y, 4); + } + else + { + return new sbyte4((sbyte)compareto(x.x, y.x), + (sbyte)compareto(x.y, y.y), + (sbyte)compareto(x.z, y.z), + (sbyte)compareto(x.w, y.w)); + } + } + + /// Returns an with each element set to -1 if the corresponding value in is smaller than the corresponding value in , 1 if the corresponding value in is greater than the corresponding value in or 0 if both are equal. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte8 compareto(quarter8 x, quarter8 y) + { + if (Sse2.IsSse2Supported) + { + return Xse.cmp_pq(x, y, 8); + } + else + { + return new sbyte8((sbyte)compareto(x.x0, y.x0), + (sbyte)compareto(x.x1, y.x1), + (sbyte)compareto(x.x2, y.x2), + (sbyte)compareto(x.x3, y.x3), + (sbyte)compareto(x.x4, y.x4), + (sbyte)compareto(x.x5, y.x5), + (sbyte)compareto(x.x6, y.x6), + (sbyte)compareto(x.x7, y.x7)); + } + } + + + /// Returns a with each element set to -1 if the corresponding value in is smaller than the corresponding value in , 1 if the corresponding value in is greater than the corresponding value in or 0 if both are equal. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short2 compareto(half2 x, half2 y) + { + if (Sse2.IsSse2Supported) + { + return Xse.cmp_ph(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 2); + } + else + { + return new short2((short)compareto(x.x, y.x), + (short)compareto(x.y, y.y)); + } + } + + /// Returns a with each element set to -1 if the corresponding value in is smaller than the corresponding value in , 1 if the corresponding value in is greater than the corresponding value in or 0 if both are equal. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short3 compareto(half3 x, half3 y) + { + if (Sse2.IsSse2Supported) + { + return Xse.cmp_ph(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 3); + } + else + { + return new short3((short)compareto(x.x, y.x), + (short)compareto(x.y, y.y), + (short)compareto(x.z, y.z)); + } + } + + /// Returns a with each element set to -1 if the corresponding value in is smaller than the corresponding value in , 1 if the corresponding value in is greater than the corresponding value in or 0 if both are equal. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short4 compareto(half4 x, half4 y) + { + if (Sse2.IsSse2Supported) + { + return Xse.cmp_ph(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y), 4); + } + else + { + return new short4((short)compareto(x.x, y.x), + (short)compareto(x.y, y.y), + (short)compareto(x.z, y.z), + (short)compareto(x.w, y.w)); + } + } + + /// Returns a with each element set to -1 if the corresponding value in is smaller than the corresponding value in , 1 if the corresponding value in is greater than the corresponding value in or 0 if both are equal. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short8 compareto(half8 x, half8 y) + { + if (Sse2.IsSse2Supported) + { + return Xse.cmp_ph(x, y, 8); + } + else + { + return new short8((short)compareto(x.x0, y.x0), + (short)compareto(x.x1, y.x1), + (short)compareto(x.x2, y.x2), + (short)compareto(x.x3, y.x3), + (short)compareto(x.x4, y.x4), + (short)compareto(x.x5, y.x5), + (short)compareto(x.x6, y.x6), + (short)compareto(x.x7, y.x7)); + } + } + + /// Returns an with each element set to -1 if the corresponding value in is smaller than the corresponding value in , 1 if the corresponding value in is greater than the corresponding value in or 0 if both are equal. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int2 compareto(float2 x, float2 y) { if (Sse2.IsSse2Supported) { - v128 _x = RegisterConversion.ToV128(x); - v128 _y = RegisterConversion.ToV128(y); - - return RegisterConversion.ToType(Sse2.sub_epi32(Sse.cmpgt_ps(_y, _x), Sse.cmpgt_ps(_x, _y))); + return RegisterConversion.ToInt2(Xse.cmp_ps(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); } else { @@ -836,10 +1171,7 @@ public static int3 compareto(float3 x, float3 y) { if (Sse2.IsSse2Supported) { - v128 _x = RegisterConversion.ToV128(x); - v128 _y = RegisterConversion.ToV128(y); - - return RegisterConversion.ToType(Sse2.sub_epi32(Sse.cmpgt_ps(_y, _x), Sse.cmpgt_ps(_x, _y))); + return RegisterConversion.ToInt3(Xse.cmp_ps(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); } else { @@ -855,10 +1187,7 @@ public static int4 compareto(float4 x, float4 y) { if (Sse2.IsSse2Supported) { - v128 _x = RegisterConversion.ToV128(x); - v128 _y = RegisterConversion.ToV128(y); - - return RegisterConversion.ToType(Sse2.sub_epi32(Sse.cmpgt_ps(_y, _x), Sse.cmpgt_ps(_x, _y))); + return RegisterConversion.ToInt4(Xse.cmp_ps(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y))); } else { @@ -875,7 +1204,7 @@ public static int8 compareto(float8 x, float8 y) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_sub_epi32(Avx.mm256_cmp_ps(y, x, (int)Avx.CMP.GT_OS), Avx.mm256_cmp_ps(x, y, (int)Avx.CMP.GT_OS)); + return Xse.mm256_cmp_ps(x, y); } else { @@ -891,10 +1220,7 @@ public static long2 compareto(double2 x, double2 y) { if (Sse2.IsSse2Supported) { - v128 _x = RegisterConversion.ToV128(x); - v128 _y = RegisterConversion.ToV128(y); - - return Sse2.sub_epi64(Sse2.cmpgt_pd(_y, _x), Sse2.cmpgt_pd(_x, _y)); + return Xse.cmp_pd(RegisterConversion.ToV128(x), RegisterConversion.ToV128(y)); } else { @@ -909,10 +1235,7 @@ public static long3 compareto(double3 x, double3 y) { if (Avx2.IsAvx2Supported) { - v256 _x = RegisterConversion.ToV256(x); - v256 _y = RegisterConversion.ToV256(y); - - return Avx2.mm256_sub_epi64(Avx.mm256_cmp_pd(_y, _x, (int)Avx.CMP.GT_OS), Avx.mm256_cmp_pd(_x, _y, (int)Avx.CMP.GT_OS)); + return Xse.mm256_cmp_pd(RegisterConversion.ToV256(x), RegisterConversion.ToV256(y)); } else { @@ -927,10 +1250,7 @@ public static long4 compareto(double4 x, double4 y) { if (Avx2.IsAvx2Supported) { - v256 _x = RegisterConversion.ToV256(x); - v256 _y = RegisterConversion.ToV256(y); - - return Avx2.mm256_sub_epi64(Avx.mm256_cmp_pd(_y, _x, (int)Avx.CMP.GT_OS), Avx.mm256_cmp_pd(_x, _y, (int)Avx.CMP.GT_OS)); + return Xse.mm256_cmp_pd(RegisterConversion.ToV256(x), RegisterConversion.ToV256(y)); } else { diff --git a/Runtime/Math Lib/Functions/Comparison/Is a Power of 2.cs b/Runtime/Math Lib/Functions/Comparison/Is a Power of 2.cs index e24ecca..7cec378 100644 --- a/Runtime/Math Lib/Functions/Comparison/Is a Power of 2.cs +++ b/Runtime/Math Lib/Functions/Comparison/Is a Power of 2.cs @@ -51,8 +51,10 @@ public static bool2 ispow2(byte2 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue8(Sse2.andnot_si128(Sse2.cmpeq_epi8(x, ZERO), - Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); + v128 results = RegisterConversion.IsTrue8(Sse2.andnot_si128(Sse2.cmpeq_epi8(x, ZERO), + Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); + + return *(bool2*)&results; } else { @@ -69,8 +71,10 @@ public static bool3 ispow2(byte3 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue8(Sse2.andnot_si128(Sse2.cmpeq_epi8(x, ZERO), - Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); + v128 results = RegisterConversion.IsTrue8(Sse2.andnot_si128(Sse2.cmpeq_epi8(x, ZERO), + Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); + + return *(bool3*)&results; } else { @@ -87,8 +91,10 @@ public static bool4 ispow2(byte4 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue8(Sse2.andnot_si128(Sse2.cmpeq_epi8(x, ZERO), - Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); + v128 results = RegisterConversion.IsTrue8(Sse2.andnot_si128(Sse2.cmpeq_epi8(x, ZERO), + Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); + + return *(bool4*)&results; } else { @@ -105,8 +111,8 @@ public static bool8 ispow2(byte8 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue8(Sse2.andnot_si128(Sse2.cmpeq_epi8(x, ZERO), - Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); + return RegisterConversion.IsTrue8(Sse2.andnot_si128(Sse2.cmpeq_epi8(x, ZERO), + Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); } else { @@ -123,8 +129,8 @@ public static bool16 ispow2(byte16 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue8(Sse2.andnot_si128(Sse2.cmpeq_epi8(x, ZERO), - Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); + return RegisterConversion.IsTrue8(Sse2.andnot_si128(Sse2.cmpeq_epi8(x, ZERO), + Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); } else { @@ -167,8 +173,10 @@ public static bool2 ispow2(sbyte2 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue8(Sse2.and_si128(Sse2.cmpgt_epi8(x, ZERO), - Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); + v128 results = RegisterConversion.IsTrue8(Sse2.and_si128(Sse2.cmpgt_epi8(x, ZERO), + Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); + + return *(bool2*)&results; } else { @@ -185,8 +193,10 @@ public static bool3 ispow2(sbyte3 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue8(Sse2.and_si128(Sse2.cmpgt_epi8(x, ZERO), - Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); + v128 results = RegisterConversion.IsTrue8(Sse2.and_si128(Sse2.cmpgt_epi8(x, ZERO), + Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); + + return *(bool3*)&results; } else { @@ -203,8 +213,10 @@ public static bool4 ispow2(sbyte4 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue8(Sse2.and_si128(Sse2.cmpgt_epi8(x, ZERO), - Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); + v128 results = RegisterConversion.IsTrue8(Sse2.and_si128(Sse2.cmpgt_epi8(x, ZERO), + Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); + + return *(bool4*)&results; } else { @@ -221,8 +233,8 @@ public static bool8 ispow2(sbyte8 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue8(Sse2.and_si128(Sse2.cmpgt_epi8(x, ZERO), - Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); + return RegisterConversion.IsTrue8(Sse2.and_si128(Sse2.cmpgt_epi8(x, ZERO), + Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); } else { @@ -239,8 +251,8 @@ public static bool16 ispow2(sbyte16 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue8(Sse2.and_si128(Sse2.cmpgt_epi8(x, ZERO), - Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); + return RegisterConversion.IsTrue8(Sse2.and_si128(Sse2.cmpgt_epi8(x, ZERO), + Sse2.cmpeq_epi8(ZERO, x & (x + ALL_ONES)))); } else { @@ -283,8 +295,10 @@ public static bool2 ispow2(ushort2 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue16(Sse2.andnot_si128(Sse2.cmpeq_epi16(x, ZERO), - Sse2.cmpeq_epi16(ZERO, x & (x + ALL_ONES)))); + v128 results = RegisterConversion.IsTrue16(Sse2.andnot_si128(Sse2.cmpeq_epi16(x, ZERO), + Sse2.cmpeq_epi16(ZERO, x & (x + ALL_ONES)))); + + return *(bool2*)&results; } else { @@ -301,8 +315,10 @@ public static bool3 ispow2(ushort3 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue16(Sse2.andnot_si128(Sse2.cmpeq_epi16(x, ZERO), - Sse2.cmpeq_epi16(ZERO, x & (x + ALL_ONES)))); + v128 results = RegisterConversion.IsTrue16(Sse2.andnot_si128(Sse2.cmpeq_epi16(x, ZERO), + Sse2.cmpeq_epi16(ZERO, x & (x + ALL_ONES)))); + + return *(bool3*)&results; } else { @@ -319,8 +335,10 @@ public static bool4 ispow2(ushort4 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue16(Sse2.andnot_si128(Sse2.cmpeq_epi16(x, ZERO), - Sse2.cmpeq_epi16(ZERO, x & (x + ALL_ONES)))); + v128 results = RegisterConversion.IsTrue16(Sse2.andnot_si128(Sse2.cmpeq_epi16(x, ZERO), + Sse2.cmpeq_epi16(ZERO, x & (x + ALL_ONES)))); + + return *(bool4*)&results; } else { @@ -337,8 +355,8 @@ public static bool8 ispow2(ushort8 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue16(Sse2.andnot_si128(Sse2.cmpeq_epi16(x, ZERO), - Sse2.cmpeq_epi16(ZERO, x & (x + ALL_ONES)))); + return RegisterConversion.IsTrue16(Sse2.andnot_si128(Sse2.cmpeq_epi16(x, ZERO), + Sse2.cmpeq_epi16(ZERO, x & (x + ALL_ONES)))); } else { @@ -381,8 +399,10 @@ public static bool2 ispow2(short2 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue16(Sse2.and_si128(Sse2.cmpgt_epi16(x, ZERO), - Sse2.cmpeq_epi16(ZERO, x & (x + ALL_ONES)))); + v128 results = RegisterConversion.IsTrue16(Sse2.and_si128(Sse2.cmpgt_epi16(x, ZERO), + Sse2.cmpeq_epi16(ZERO, x & (x + ALL_ONES)))); + + return *(bool2*)&results; } else { @@ -399,8 +419,10 @@ public static bool3 ispow2(short3 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue16(Sse2.and_si128(Sse2.cmpgt_epi16(x, ZERO), - Sse2.cmpeq_epi16(ZERO, x & (x + ALL_ONES)))); + v128 results = RegisterConversion.IsTrue16(Sse2.and_si128(Sse2.cmpgt_epi16(x, ZERO), + Sse2.cmpeq_epi16(ZERO, x & (x + ALL_ONES)))); + + return *(bool3*)&results; } else { @@ -417,8 +439,10 @@ public static bool4 ispow2(short4 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue16(Sse2.and_si128(Sse2.cmpgt_epi16(x, ZERO), - Sse2.cmpeq_epi16(ZERO, x & (x + ALL_ONES)))); + v128 results = RegisterConversion.IsTrue16(Sse2.and_si128(Sse2.cmpgt_epi16(x, ZERO), + Sse2.cmpeq_epi16(ZERO, x & (x + ALL_ONES)))); + + return *(bool4*)&results; } else { @@ -435,8 +459,8 @@ public static bool8 ispow2(short8 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue16(Sse2.and_si128(Sse2.cmpgt_epi16(x, ZERO), - Sse2.cmpeq_epi16(ZERO, x & (x + ALL_ONES)))); + return RegisterConversion.IsTrue16(Sse2.and_si128(Sse2.cmpgt_epi16(x, ZERO), + Sse2.cmpeq_epi16(ZERO, x & (x + ALL_ONES)))); } else { @@ -517,8 +541,10 @@ public static bool2 ispow2(ulong2 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue64(Sse2.andnot_si128(Xse.cmpeq_epi64(x, ZERO), + int results = RegisterConversion.IsTrue64(Sse2.andnot_si128(Xse.cmpeq_epi64(x, ZERO), Xse.cmpeq_epi64(ZERO, x & (x + ALL_ONES)))); + + return *(bool2*)&results; } else { @@ -535,8 +561,10 @@ public static bool3 ispow2(ulong3 x) v256 ZERO = Avx.mm256_setzero_si256(); v256 ALL_ONES = Xse.mm256_setall_si256(); - return RegisterConversion.IsTrue64(Avx2.mm256_andnot_si256(Avx2.mm256_cmpeq_epi64(x, ZERO), + int results = RegisterConversion.IsTrue64(Avx2.mm256_andnot_si256(Avx2.mm256_cmpeq_epi64(x, ZERO), Avx2.mm256_cmpeq_epi64(ZERO, x & (x + ALL_ONES)))); + + return *(bool3*)&results; } else { @@ -553,8 +581,10 @@ public static bool4 ispow2(ulong4 x) v256 ZERO = Avx.mm256_setzero_si256(); v256 ALL_ONES = Xse.mm256_setall_si256(); - return RegisterConversion.IsTrue64(Avx2.mm256_andnot_si256(Avx2.mm256_cmpeq_epi64(x, ZERO), + int results = RegisterConversion.IsTrue64(Avx2.mm256_andnot_si256(Avx2.mm256_cmpeq_epi64(x, ZERO), Avx2.mm256_cmpeq_epi64(ZERO, x & (x + ALL_ONES)))); + + return *(bool4*)&results; } else { @@ -579,8 +609,10 @@ public static bool2 ispow2(long2 x) v128 ZERO = Sse2.setzero_si128(); v128 ALL_ONES = Xse.setall_si128(); - return RegisterConversion.IsTrue64(Sse2.and_si128(Xse.cmpgt_epi64(x, ZERO), + int results = RegisterConversion.IsTrue64(Sse2.and_si128(Xse.cmpgt_epi64(x, ZERO), Xse.cmpeq_epi64(ZERO, x & (x + ALL_ONES)))); + + return *(bool2*)&results; } else { @@ -597,8 +629,10 @@ public static bool3 ispow2(long3 x) v256 ZERO = Avx.mm256_setzero_si256(); v256 ALL_ONES = Xse.mm256_setall_si256(); - return RegisterConversion.IsTrue64(Avx2.mm256_and_si256(Xse.mm256_cmpgt_epi64(x, ZERO, 3), + int results = RegisterConversion.IsTrue64(Avx2.mm256_and_si256(Xse.mm256_cmpgt_epi64(x, ZERO, 3), Avx2.mm256_cmpeq_epi64(ZERO, x & (x + ALL_ONES)))); + + return *(bool3*)&results; } else { @@ -615,8 +649,10 @@ public static bool4 ispow2(long4 x) v256 ZERO = Avx.mm256_setzero_si256(); v256 ALL_ONES = Xse.mm256_setall_si256(); - return RegisterConversion.IsTrue64(Avx2.mm256_and_si256(Xse.mm256_cmpgt_epi64(x, ZERO, 4), + int results = RegisterConversion.IsTrue64(Avx2.mm256_and_si256(Xse.mm256_cmpgt_epi64(x, ZERO, 4), Avx2.mm256_cmpeq_epi64(ZERO, x & (x + ALL_ONES)))); + + return *(bool4*)&results; } else { diff --git a/Runtime/Math Lib/Functions/Comparison/Is in Range.cs b/Runtime/Math Lib/Functions/Comparison/Is in Range.cs index e4ee74f..803b271 100644 --- a/Runtime/Math Lib/Functions/Comparison/Is in Range.cs +++ b/Runtime/Math Lib/Functions/Comparison/Is in Range.cs @@ -298,7 +298,9 @@ public static bool2 isinrange(long2 x, long2 min, long2 max) v128 cmpMin = Xse.cmpgt_epi64(min, x); v128 cmpMax = Xse.cmpgt_epi64(x, max); - return RegisterConversion.IsFalse64(Sse2.or_si128(cmpMin, cmpMax)); + int results = RegisterConversion.IsFalse64(Sse2.or_si128(cmpMin, cmpMax)); + + return *(bool2*)&results; } else { @@ -316,7 +318,9 @@ public static bool3 isinrange(long3 x, long3 min, long3 max) v256 cmpMin = Xse.mm256_cmpgt_epi64(min, x, 3); v256 cmpMax = Xse.mm256_cmpgt_epi64(x, max, 3); - return RegisterConversion.IsFalse64(Avx2.mm256_or_si256(cmpMax, cmpMin)); + int results = RegisterConversion.IsFalse64(Avx2.mm256_or_si256(cmpMax, cmpMin)); + + return *(bool3*)&results; } else { @@ -334,7 +338,9 @@ public static bool4 isinrange(long4 x, long4 min, long4 max) v256 cmpMin = Xse.mm256_cmpgt_epi64(min, x, 4); v256 cmpMax = Xse.mm256_cmpgt_epi64(x, max, 4); - return RegisterConversion.IsFalse64(Avx2.mm256_or_si256(cmpMax, cmpMin)); + int results = RegisterConversion.IsFalse64(Avx2.mm256_or_si256(cmpMax, cmpMin)); + + return *(bool4*)&results; } else { @@ -360,7 +366,9 @@ public static bool2 isinrange(ulong2 x, ulong2 min, ulong2 max) v128 cmpMin = Xse.cmpgt_epu64(min, x); v128 cmpMax = Xse.cmpgt_epu64(x, max); - return RegisterConversion.IsFalse64(Sse2.or_si128(cmpMax, cmpMin)); + int results = RegisterConversion.IsFalse64(Sse2.or_si128(cmpMax, cmpMin)); + + return *(bool2*)&results; } else { @@ -378,7 +386,9 @@ public static bool3 isinrange(ulong3 x, ulong3 min, ulong3 max) v256 cmpMin = Xse.mm256_cmpgt_epu64(min, x, 3); v256 cmpMax = Xse.mm256_cmpgt_epu64(x, max, 3); - return RegisterConversion.IsFalse64(Avx2.mm256_or_si256(cmpMax, cmpMin)); + int results = RegisterConversion.IsFalse64(Avx2.mm256_or_si256(cmpMax, cmpMin)); + + return *(bool3*)&results; } else { @@ -396,7 +406,9 @@ public static bool4 isinrange(ulong4 x, ulong4 min, ulong4 max) v256 cmpMin = Xse.mm256_cmpgt_epu64(min, x, 4); v256 cmpMax = Xse.mm256_cmpgt_epu64(x, max, 4); - return RegisterConversion.IsFalse64(Avx2.mm256_or_si256(cmpMax, cmpMin)); + int results = RegisterConversion.IsFalse64(Avx2.mm256_or_si256(cmpMax, cmpMin)); + + return *(bool4*)&results; } else { diff --git a/Runtime/Math Lib/Functions/Comparison/Selection/Conditionally Negate.cs b/Runtime/Math Lib/Functions/Comparison/Selection/Conditionally Negate.cs index b2cc321..193eec9 100644 --- a/Runtime/Math Lib/Functions/Comparison/Selection/Conditionally Negate.cs +++ b/Runtime/Math Lib/Functions/Comparison/Selection/Conditionally Negate.cs @@ -526,7 +526,7 @@ public static int2 negate(int2 x, bool2 p) { if (Ssse3.IsSsse3Supported) { - return RegisterConversion.ToType(Ssse3.sign_epi32(RegisterConversion.ToV128(x), new v128((int)(p.x ? -1 : 1), (int)(p.y ? -1 : 1), 0, 0))); + return RegisterConversion.ToInt2(Ssse3.sign_epi32(RegisterConversion.ToV128(x), new v128((int)(p.x ? -1 : 1), (int)(p.y ? -1 : 1), 0, 0))); } } @@ -547,7 +547,7 @@ public static int3 negate(int3 x, bool3 p) { if (Ssse3.IsSsse3Supported) { - return RegisterConversion.ToType(Ssse3.sign_epi32(RegisterConversion.ToV128(x), new v128((int)(p.x ? -1 : 1), (int)(p.y ? -1 : 1), (int)(p.z ? -1 : 1), 0))); + return RegisterConversion.ToInt3(Ssse3.sign_epi32(RegisterConversion.ToV128(x), new v128((int)(p.x ? -1 : 1), (int)(p.y ? -1 : 1), (int)(p.z ? -1 : 1), 0))); } } @@ -569,7 +569,7 @@ public static int4 negate(int4 x, bool4 p) { if (Ssse3.IsSsse3Supported) { - return RegisterConversion.ToType(Ssse3.sign_epi32(RegisterConversion.ToV128(x), new v128((int)(p.x ? -1 : 1), (int)(p.y ? -1 : 1), (int)(p.z ? -1 : 1), (int)(p.w ? -1 : 1)))); + return RegisterConversion.ToInt4(Ssse3.sign_epi32(RegisterConversion.ToV128(x), new v128((int)(p.x ? -1 : 1), (int)(p.y ? -1 : 1), (int)(p.z ? -1 : 1), (int)(p.w ? -1 : 1)))); } } diff --git a/Runtime/Math Lib/Functions/Comparison/Selection/Max Magnitude.cs b/Runtime/Math Lib/Functions/Comparison/Selection/Max Magnitude.cs index 54d072c..d5f5991 100644 --- a/Runtime/Math Lib/Functions/Comparison/Selection/Max Magnitude.cs +++ b/Runtime/Math Lib/Functions/Comparison/Selection/Max Magnitude.cs @@ -560,14 +560,14 @@ public static int maxmag(int a, int b) return math.abs(a) > math.abs(b) ? a : b; } - /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. /// A '' with its flag set returns undefined results for any + component pair that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int2 maxmag(int2 a, int2 b, Promise noOverFlow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.maxmag_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), noOverFlow.Promises(Promise.NoOverflow), 2)); + return RegisterConversion.ToInt2(Xse.maxmag_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), noOverFlow.Promises(Promise.NoOverflow), 2)); } else if (Arm.Neon.IsNeonSupported) { @@ -579,14 +579,14 @@ public static int2 maxmag(int2 a, int2 b, Promise noOverFlow = Promise.Nothing) } } - /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. /// A '' with its flag set returns undefined results for any + component pair that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int3 maxmag(int3 a, int3 b, Promise noOverFlow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.maxmag_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); + return RegisterConversion.ToInt3(Xse.maxmag_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); } else if (Arm.Neon.IsNeonSupported) { @@ -598,14 +598,14 @@ public static int3 maxmag(int3 a, int3 b, Promise noOverFlow = Promise.Nothing) } } - /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. /// A '' with its flag set returns undefined results for any + component pair that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int4 maxmag(int4 a, int4 b, Promise noOverFlow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.maxmag_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), noOverFlow.Promises(Promise.NoOverflow), 3)); + return RegisterConversion.ToInt4(Xse.maxmag_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), noOverFlow.Promises(Promise.NoOverflow), 3)); } else if (Arm.Neon.IsNeonSupported) { @@ -700,13 +700,13 @@ public static float maxmag(float a, float b) } } - /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float2 maxmag(float2 a, float2 b) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.maxmag_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); + return RegisterConversion.ToFloat2(Xse.maxmag_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); } else if (Arm.Neon.IsNeonSupported) { @@ -718,13 +718,13 @@ public static float2 maxmag(float2 a, float2 b) } } - /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float3 maxmag(float3 a, float3 b) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.maxmag_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); + return RegisterConversion.ToFloat3(Xse.maxmag_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); } else if (Arm.Neon.IsNeonSupported) { @@ -736,13 +736,13 @@ public static float3 maxmag(float3 a, float3 b) } } - /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float4 maxmag(float4 a, float4 b) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.maxmag_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); + return RegisterConversion.ToFloat4(Xse.maxmag_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); } else if (Arm.Neon.IsNeonSupported) { @@ -783,13 +783,13 @@ public static double maxmag(double a, double b) } } - /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double2 maxmag(double2 a, double2 b) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.maxmag_pd(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); + return RegisterConversion.ToDouble2(Xse.maxmag_pd(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); } else if (Arm.Neon.IsNeonSupported) { @@ -801,13 +801,13 @@ public static double2 maxmag(double2 a, double2 b) } } - /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double3 maxmag(double3 a, double3 b) { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Xse.mm256_maxmag_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), 3)); + return RegisterConversion.ToDouble3(Xse.mm256_maxmag_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), 3)); } else if (Arm.Neon.IsNeonSupported) { @@ -819,13 +819,13 @@ public static double3 maxmag(double3 a, double3 b) } } - /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise maximum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double4 maxmag(double4 a, double4 b) { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Xse.mm256_maxmag_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), 4)); + return RegisterConversion.ToDouble4(Xse.mm256_maxmag_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), 4)); } else if (Arm.Neon.IsNeonSupported) { diff --git a/Runtime/Math Lib/Functions/Comparison/Selection/Max.cs b/Runtime/Math Lib/Functions/Comparison/Selection/Max.cs index 6c04d1a..2212d65 100644 --- a/Runtime/Math Lib/Functions/Comparison/Selection/Max.cs +++ b/Runtime/Math Lib/Functions/Comparison/Selection/Max.cs @@ -51,6 +51,11 @@ public static v128 max_epi64(v128 a, v128 b) { if (Sse2.IsSse2Supported) { + if (constexpr.ALL_GE_EPI64(a, int.MinValue) && constexpr.ALL_GE_EPI64(b, int.MinValue) && constexpr.ALL_LE_EPI64(a, int.MaxValue) && constexpr.ALL_LE_EPI64(b, int.MaxValue)) + { + return max_epi32(a, b); + } + return blendv_si128(a, b, cmpgt_epi64(b, a)); } else throw new IllegalInstructionException(); @@ -62,6 +67,11 @@ public static v256 mm256_max_epi64(v256 a, v256 b, byte elements = 4) { if (Avx2.IsAvx2Supported) { + if (constexpr.ALL_GE_EPI64(a, int.MinValue, elements) && constexpr.ALL_GE_EPI64(b, int.MinValue, elements) && constexpr.ALL_LE_EPI64(a, int.MaxValue, elements) && constexpr.ALL_LE_EPI64(b, int.MaxValue, elements)) + { + return Avx2.mm256_max_epi32(a, b); + } + return mm256_blendv_si256(a, b, mm256_cmpgt_epi64(b, a, elements)); } else throw new IllegalInstructionException(); @@ -111,16 +121,26 @@ public static v128 max_epu64(v128 a, v128 b) { if (Sse2.IsSse2Supported) { + if (constexpr.ALL_LE_EPU64(a, uint.MaxValue) && constexpr.ALL_LE_EPU64(b, uint.MaxValue)) + { + return max_epu32(a, b); + } + return blendv_si128(a, b, cmpgt_epu64(b, a)); } else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v256 mm256_max_epu64(v256 a, v256 b) + public static v256 mm256_max_epu64(v256 a, v256 b, byte elements = 4) { if (Avx2.IsAvx2Supported) { + if (constexpr.ALL_LE_EPU64(a, uint.MaxValue, elements) && constexpr.ALL_LE_EPU64(b, uint.MaxValue, elements)) + { + return Avx2.mm256_max_epu32(a, b); + } + return mm256_blendv_si256(a, b, mm256_cmpgt_epu64(b, a)); } else throw new IllegalInstructionException(); @@ -536,7 +556,7 @@ public static ulong3 max(ulong3 a, ulong3 b) { if (Avx2.IsAvx2Supported) { - return Xse.mm256_max_epu64(a, b); + return Xse.mm256_max_epu64(a, b, 3); } else { @@ -550,7 +570,7 @@ public static ulong4 max(ulong4 a, ulong4 b) { if (Avx2.IsAvx2Supported) { - return Xse.mm256_max_epu64(a, b); + return Xse.mm256_max_epu64(a, b, 4); } else { diff --git a/Runtime/Math Lib/Functions/Comparison/Selection/Min Magnitude.cs b/Runtime/Math Lib/Functions/Comparison/Selection/Min Magnitude.cs index f659f0a..677345b 100644 --- a/Runtime/Math Lib/Functions/Comparison/Selection/Min Magnitude.cs +++ b/Runtime/Math Lib/Functions/Comparison/Selection/Min Magnitude.cs @@ -559,14 +559,14 @@ public static int minmag(int a, int b) return math.abs(a) > math.abs(b) ? b : a; } - /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. /// A '' with its flag set returns undefined results for any + component pair that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int2 minmag(int2 a, int2 b, Promise noOverFlow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.minmag_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), noOverFlow.Promises(Promise.NoOverflow), 2)); + return RegisterConversion.ToInt2(Xse.minmag_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), noOverFlow.Promises(Promise.NoOverflow), 2)); } else if (Arm.Neon.IsNeonSupported) { @@ -578,14 +578,14 @@ public static int2 minmag(int2 a, int2 b, Promise noOverFlow = Promise.Nothing) } } - /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. /// A '' with its flag set returns undefined results for any + component pair that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int3 minmag(int3 a, int3 b, Promise noOverFlow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.minmag_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), noOverFlow.Promises(Promise.NoOverflow), 3)); + return RegisterConversion.ToInt3(Xse.minmag_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), noOverFlow.Promises(Promise.NoOverflow), 3)); } else if (Arm.Neon.IsNeonSupported) { @@ -597,14 +597,14 @@ public static int3 minmag(int3 a, int3 b, Promise noOverFlow = Promise.Nothing) } } - /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. /// A '' with its flag set returns undefined results for any + component pair that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int4 minmag(int4 a, int4 b, Promise noOverFlow = Promise.Nothing) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.minmag_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), noOverFlow.Promises(Promise.NoOverflow), 4)); + return RegisterConversion.ToInt4(Xse.minmag_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), noOverFlow.Promises(Promise.NoOverflow), 4)); } else if (Arm.Neon.IsNeonSupported) { @@ -699,13 +699,13 @@ public static float minmag(float a, float b) } } - /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float2 minmag(float2 a, float2 b) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.minmag_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 2)); + return RegisterConversion.ToFloat2(Xse.minmag_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 2)); } else if (Arm.Neon.IsNeonSupported) { @@ -717,13 +717,13 @@ public static float2 minmag(float2 a, float2 b) } } - /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float3 minmag(float3 a, float3 b) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.minmag_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 3)); + return RegisterConversion.ToFloat3(Xse.minmag_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 3)); } else if (Arm.Neon.IsNeonSupported) { @@ -735,13 +735,13 @@ public static float3 minmag(float3 a, float3 b) } } - /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float4 minmag(float4 a, float4 b) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.minmag_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 4)); + return RegisterConversion.ToFloat4(Xse.minmag_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), 4)); } else if (Arm.Neon.IsNeonSupported) { @@ -782,13 +782,13 @@ public static double minmag(double a, double b) } } - /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double2 minmag(double2 a, double2 b) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.minmag_pd(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); + return RegisterConversion.ToDouble2(Xse.minmag_pd(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b))); } else if (Arm.Neon.IsNeonSupported) { @@ -800,13 +800,13 @@ public static double2 minmag(double2 a, double2 b) } } - /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double3 minmag(double3 a, double3 b) { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Xse.mm256_minmag_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), 3)); + return RegisterConversion.ToDouble3(Xse.mm256_minmag_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), 3)); } else if (Arm.Neon.IsNeonSupported) { @@ -818,13 +818,13 @@ public static double3 minmag(double3 a, double3 b) } } - /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. + /// Returns the componentwise minimum of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return value is undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double4 minmag(double4 a, double4 b) { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Xse.mm256_minmag_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), 4)); + return RegisterConversion.ToDouble4(Xse.mm256_minmag_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), 4)); } else if (Arm.Neon.IsNeonSupported) { diff --git a/Runtime/Math Lib/Functions/Comparison/Selection/Min Max Magnitude.cs b/Runtime/Math Lib/Functions/Comparison/Selection/Min Max Magnitude.cs index 0891759..d281a1b 100644 --- a/Runtime/Math Lib/Functions/Comparison/Selection/Min Max Magnitude.cs +++ b/Runtime/Math Lib/Functions/Comparison/Selection/Min Max Magnitude.cs @@ -498,7 +498,7 @@ public static void minmaxmag(short16 a, short16 b, [NoAlias] out short16 minmag, } - /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. + /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. /// A '' with its flag set returns undefined results for any + component pair that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void minmaxmag(int2 a, int2 b, [NoAlias] out int2 minmag, [NoAlias] out int2 maxmag, Promise noOverFlow = Promise.Nothing) @@ -507,8 +507,8 @@ public static void minmaxmag(int2 a, int2 b, [NoAlias] out int2 minmag, [NoAlias { Xse.minmaxmag_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 min, out v128 max, noOverFlow.Promises(Promise.NoOverflow), 2); - minmag = RegisterConversion.ToType(min); - maxmag = RegisterConversion.ToType(max); + minmag = RegisterConversion.ToInt2(min); + maxmag = RegisterConversion.ToInt2(max); } else { @@ -517,7 +517,7 @@ public static void minmaxmag(int2 a, int2 b, [NoAlias] out int2 minmag, [NoAlias } } - /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. + /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. /// A '' with its flag set returns undefined results for any + component pair that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void minmaxmag(int3 a, int3 b, [NoAlias] out int3 minmag, [NoAlias] out int3 maxmag, Promise noOverFlow = Promise.Nothing) @@ -526,8 +526,8 @@ public static void minmaxmag(int3 a, int3 b, [NoAlias] out int3 minmag, [NoAlias { Xse.minmaxmag_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 min, out v128 max, noOverFlow.Promises(Promise.NoOverflow), 3); - minmag = RegisterConversion.ToType(min); - maxmag = RegisterConversion.ToType(max); + minmag = RegisterConversion.ToInt3(min); + maxmag = RegisterConversion.ToInt3(max); } else { @@ -536,7 +536,7 @@ public static void minmaxmag(int3 a, int3 b, [NoAlias] out int3 minmag, [NoAlias } } - /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. + /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. /// A '' with its flag set returns undefined results for any + component pair that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void minmaxmag(int4 a, int4 b, [NoAlias] out int4 minmag, [NoAlias] out int4 maxmag, Promise noOverFlow = Promise.Nothing) @@ -545,8 +545,8 @@ public static void minmaxmag(int4 a, int4 b, [NoAlias] out int4 minmag, [NoAlias { Xse.minmaxmag_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 min, out v128 max, noOverFlow.Promises(Promise.NoOverflow), 4); - minmag = RegisterConversion.ToType(min); - maxmag = RegisterConversion.ToType(max); + minmag = RegisterConversion.ToInt4(min); + maxmag = RegisterConversion.ToInt4(max); } else { @@ -641,7 +641,7 @@ public static void minmaxmag(long4 a, long4 b, [NoAlias] out long4 minmag, [NoAl } - /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. + /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void minmaxmag(float2 a, float2 b, [NoAlias] out float2 minmag, [NoAlias] out float2 maxmag) { @@ -649,8 +649,8 @@ public static void minmaxmag(float2 a, float2 b, [NoAlias] out float2 minmag, [N { Xse.minmaxmag_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 min, out v128 max); - minmag = RegisterConversion.ToType(min); - maxmag = RegisterConversion.ToType(max); + minmag = RegisterConversion.ToFloat2(min); + maxmag = RegisterConversion.ToFloat2(max); } else { @@ -659,7 +659,7 @@ public static void minmaxmag(float2 a, float2 b, [NoAlias] out float2 minmag, [N } } - /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. + /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void minmaxmag(float3 a, float3 b, [NoAlias] out float3 minmag, [NoAlias] out float3 maxmag) { @@ -667,8 +667,8 @@ public static void minmaxmag(float3 a, float3 b, [NoAlias] out float3 minmag, [N { Xse.minmaxmag_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 min, out v128 max); - minmag = RegisterConversion.ToType(min); - maxmag = RegisterConversion.ToType(max); + minmag = RegisterConversion.ToFloat3(min); + maxmag = RegisterConversion.ToFloat3(max); } else { @@ -677,7 +677,7 @@ public static void minmaxmag(float3 a, float3 b, [NoAlias] out float3 minmag, [N } } - /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. + /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void minmaxmag(float4 a, float4 b, [NoAlias] out float4 minmag, [NoAlias] out float4 maxmag) { @@ -685,8 +685,8 @@ public static void minmaxmag(float4 a, float4 b, [NoAlias] out float4 minmag, [N { Xse.minmaxmag_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 min, out v128 max); - minmag = RegisterConversion.ToType(min); - maxmag = RegisterConversion.ToType(max); + minmag = RegisterConversion.ToFloat4(min); + maxmag = RegisterConversion.ToFloat4(max); } else { @@ -717,7 +717,7 @@ public static void minmaxmag(float8 a, float8 b, [NoAlias] out float8 minmag, [N } - /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. + /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void minmaxmag(double2 a, double2 b, [NoAlias] out double2 minmag, [NoAlias] out double2 maxmag) { @@ -725,8 +725,8 @@ public static void minmaxmag(double2 a, double2 b, [NoAlias] out double2 minmag, { Xse.minmaxmag_pd(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 min, out v128 max); - minmag = RegisterConversion.ToType(min); - maxmag = RegisterConversion.ToType(max); + minmag = RegisterConversion.ToDouble2(min); + maxmag = RegisterConversion.ToDouble2(max); } else { @@ -735,7 +735,7 @@ public static void minmaxmag(double2 a, double2 b, [NoAlias] out double2 minmag, } } - /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. + /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void minmaxmag(double3 a, double3 b, [NoAlias] out double3 minmag, [NoAlias] out double3 maxmag) { @@ -743,8 +743,8 @@ public static void minmaxmag(double3 a, double3 b, [NoAlias] out double3 minmag, { Xse.mm256_minmaxmag_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), out v256 min, out v256 max); - minmag = RegisterConversion.ToType(min); - maxmag = RegisterConversion.ToType(max); + minmag = RegisterConversion.ToDouble3(min); + maxmag = RegisterConversion.ToDouble3(max); } else { @@ -755,7 +755,7 @@ public static void minmaxmag(double3 a, double3 b, [NoAlias] out double3 minmag, } } - /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. + /// Returns the componentwise minimum '' and maximum '' of two s with regard to their magnitude. If abs() is equal to abs() for a component, the sign of the return values are undefined for that component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void minmaxmag(double4 a, double4 b, [NoAlias] out double4 minmag, [NoAlias] out double4 maxmag) { @@ -763,8 +763,8 @@ public static void minmaxmag(double4 a, double4 b, [NoAlias] out double4 minmag, { Xse.mm256_minmaxmag_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), out v256 min, out v256 max); - minmag = RegisterConversion.ToType(min); - maxmag = RegisterConversion.ToType(max); + minmag = RegisterConversion.ToDouble4(min); + maxmag = RegisterConversion.ToDouble4(max); } else { diff --git a/Runtime/Math Lib/Functions/Comparison/Selection/Min.cs b/Runtime/Math Lib/Functions/Comparison/Selection/Min.cs index 5e2ddc9..5d69a3a 100644 --- a/Runtime/Math Lib/Functions/Comparison/Selection/Min.cs +++ b/Runtime/Math Lib/Functions/Comparison/Selection/Min.cs @@ -51,6 +51,11 @@ public static v128 min_epi64(v128 a, v128 b) { if (Sse2.IsSse2Supported) { + if (constexpr.ALL_GE_EPI64(a, int.MinValue) && constexpr.ALL_GE_EPI64(b, int.MinValue) && constexpr.ALL_LE_EPI64(a, int.MaxValue) && constexpr.ALL_LE_EPI64(b, int.MaxValue)) + { + return min_epi32(a, b); + } + return blendv_si128(a, b, cmpgt_epi64(a, b)); } else throw new IllegalInstructionException(); @@ -61,6 +66,11 @@ public static v256 mm256_min_epi64(v256 a, v256 b, byte elements = 4) { if (Avx2.IsAvx2Supported) { + if (constexpr.ALL_GE_EPI64(a, int.MinValue, elements) && constexpr.ALL_GE_EPI64(b, int.MinValue, elements) && constexpr.ALL_LE_EPI64(a, int.MaxValue, elements) && constexpr.ALL_LE_EPI64(b, int.MaxValue, elements)) + { + return Avx2.mm256_min_epi32(a, b); + } + return mm256_blendv_si256(a, b, mm256_cmpgt_epi64(a, b, elements)); } else throw new IllegalInstructionException(); @@ -110,16 +120,26 @@ public static v128 min_epu64(v128 a, v128 b) { if (Sse2.IsSse2Supported) { + if (constexpr.ALL_LE_EPU64(a, uint.MaxValue) && constexpr.ALL_LE_EPU64(b, uint.MaxValue)) + { + return min_epu32(a, b); + } + return blendv_si128(a, b, cmpgt_epu64(a, b)); } else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v256 mm256_min_epu64(v256 a, v256 b) + public static v256 mm256_min_epu64(v256 a, v256 b, byte elements = 4) { if (Avx2.IsAvx2Supported) { + if (constexpr.ALL_LE_EPU64(a, uint.MaxValue, elements) && constexpr.ALL_LE_EPU64(b, uint.MaxValue, elements)) + { + return Avx2.mm256_min_epu32(a, b); + } + return mm256_blendv_si256(a, b, mm256_cmpgt_epu64(a, b)); } else throw new IllegalInstructionException(); @@ -535,7 +555,7 @@ public static ulong3 min(ulong3 a, ulong3 b) { if (Avx2.IsAvx2Supported) { - return Xse.mm256_min_epu64(a, b); + return Xse.mm256_min_epu64(a, b, 3); } else { @@ -549,7 +569,7 @@ public static ulong4 min(ulong4 a, ulong4 b) { if (Avx2.IsAvx2Supported) { - return Xse.mm256_min_epu64(a, b); + return Xse.mm256_min_epu64(a, b, 4); } else { diff --git a/Runtime/Math Lib/Functions/Comparison/Selection/MinMax.cs b/Runtime/Math Lib/Functions/Comparison/Selection/MinMax.cs index 7ef0f06..4fb6046 100644 --- a/Runtime/Math Lib/Functions/Comparison/Selection/MinMax.cs +++ b/Runtime/Math Lib/Functions/Comparison/Selection/MinMax.cs @@ -1,7 +1,6 @@ using System.Runtime.CompilerServices; using Unity.Mathematics; using Unity.Burst; -using Unity.Burst.CompilerServices; using Unity.Burst.Intrinsics; using MaxMath.Intrinsics; @@ -682,8 +681,8 @@ public static void minmax(int2 a, int2 b, [NoAlias] out int2 min, [NoAlias] out if (Sse2.IsSse2Supported) { Xse.minmax_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 _min, out v128 _max); - min = RegisterConversion.ToType(_min); - max = RegisterConversion.ToType(_max); + min = RegisterConversion.ToInt2(_min); + max = RegisterConversion.ToInt2(_max); } else { @@ -699,8 +698,8 @@ public static void minmax(int3 a, int3 b, [NoAlias] out int3 min, [NoAlias] out if (Sse2.IsSse2Supported) { Xse.minmax_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 _min, out v128 _max); - min = RegisterConversion.ToType(_min); - max = RegisterConversion.ToType(_max); + min = RegisterConversion.ToInt3(_min); + max = RegisterConversion.ToInt3(_max); } else { @@ -716,8 +715,8 @@ public static void minmax(int4 a, int4 b, [NoAlias] out int4 min, [NoAlias] out if (Sse2.IsSse2Supported) { Xse.minmax_epi32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 _min, out v128 _max); - min = RegisterConversion.ToType(_min); - max = RegisterConversion.ToType(_max); + min = RegisterConversion.ToInt4(_min); + max = RegisterConversion.ToInt4(_max); } else { @@ -754,8 +753,8 @@ public static void minmax(uint2 a, uint2 b, [NoAlias] out uint2 min, [NoAlias] o if (Sse2.IsSse2Supported) { Xse.minmax_epu32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 _min, out v128 _max); - min = RegisterConversion.ToType(_min); - max = RegisterConversion.ToType(_max); + min = RegisterConversion.ToUInt2(_min); + max = RegisterConversion.ToUInt2(_max); } else { @@ -771,8 +770,8 @@ public static void minmax(uint3 a, uint3 b, [NoAlias] out uint3 min, [NoAlias] o if (Sse2.IsSse2Supported) { Xse.minmax_epu32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 _min, out v128 _max); - min = RegisterConversion.ToType(_min); - max = RegisterConversion.ToType(_max); + min = RegisterConversion.ToUInt3(_min); + max = RegisterConversion.ToUInt3(_max); } else { @@ -788,8 +787,8 @@ public static void minmax(uint4 a, uint4 b, [NoAlias] out uint4 min, [NoAlias] o if (Sse2.IsSse2Supported) { Xse.minmax_epu32(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 _min, out v128 _max); - min = RegisterConversion.ToType(_min); - max = RegisterConversion.ToType(_max); + min = RegisterConversion.ToUInt4(_min); + max = RegisterConversion.ToUInt4(_max); } else { @@ -936,8 +935,8 @@ public static void minmax(float2 a, float2 b, [NoAlias] out float2 min, [NoAlias if (Sse2.IsSse2Supported) { Xse.minmax_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 _min, out v128 _max); - min = RegisterConversion.ToType(_min); - max = RegisterConversion.ToType(_max); + min = RegisterConversion.ToFloat2(_min); + max = RegisterConversion.ToFloat2(_max); } else { @@ -953,8 +952,8 @@ public static void minmax(float3 a, float3 b, [NoAlias] out float3 min, [NoAlias if (Sse2.IsSse2Supported) { Xse.minmax_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 _min, out v128 _max); - min = RegisterConversion.ToType(_min); - max = RegisterConversion.ToType(_max); + min = RegisterConversion.ToFloat3(_min); + max = RegisterConversion.ToFloat3(_max); } else { @@ -970,8 +969,8 @@ public static void minmax(float4 a, float4 b, [NoAlias] out float4 min, [NoAlias if (Sse2.IsSse2Supported) { Xse.minmax_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 _min, out v128 _max); - min = RegisterConversion.ToType(_min); - max = RegisterConversion.ToType(_max); + min = RegisterConversion.ToFloat4(_min); + max = RegisterConversion.ToFloat4(_max); } else { @@ -1001,15 +1000,15 @@ public static void minmax(float8 a, float8 b, [NoAlias] out float8 min, [NoAlias } - /// Returns the componentwise minimum '' and maximum '' of two s. + /// Returns the componentwise minimum '' and maximum '' of two s. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void minmax(double2 a, double2 b, [NoAlias] out double2 min, [NoAlias] out double2 max) { if (Sse2.IsSse2Supported) { Xse.minmax_pd(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), out v128 _min, out v128 _max); - min = RegisterConversion.ToType(_min); - max = RegisterConversion.ToType(_max); + min = RegisterConversion.ToDouble2(_min); + max = RegisterConversion.ToDouble2(_max); } else { @@ -1018,15 +1017,15 @@ public static void minmax(double2 a, double2 b, [NoAlias] out double2 min, [NoAl } } - /// Returns the componentwise minimum '' and maximum '' of two s. + /// Returns the componentwise minimum '' and maximum '' of two s. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void minmax(double3 a, double3 b, [NoAlias] out double3 min, [NoAlias] out double3 max) { if (Avx2.IsAvx2Supported) { Xse.mm256_minmax_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), out v256 _min, out v256 _max); - min = RegisterConversion.ToType(_min); - max = RegisterConversion.ToType(_max); + min = RegisterConversion.ToDouble3(_min); + max = RegisterConversion.ToDouble3(_max); } else { @@ -1036,15 +1035,15 @@ public static void minmax(double3 a, double3 b, [NoAlias] out double3 min, [NoAl } } - /// Returns the componentwise minimum '' and maximum '' of two s. + /// Returns the componentwise minimum '' and maximum '' of two s. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void minmax(double4 a, double4 b, [NoAlias] out double4 min, [NoAlias] out double4 max) { if (Avx2.IsAvx2Supported) { Xse.mm256_minmax_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), out v256 _min, out v256 _max); - min = RegisterConversion.ToType(_min); - max = RegisterConversion.ToType(_max); + min = RegisterConversion.ToDouble4(_min); + max = RegisterConversion.ToDouble4(_max); } else { diff --git a/Runtime/Math Lib/Functions/Comparison/Selection/Select.cs b/Runtime/Math Lib/Functions/Comparison/Selection/Select.cs index 600bbbd..c373079 100644 --- a/Runtime/Math Lib/Functions/Comparison/Selection/Select.cs +++ b/Runtime/Math Lib/Functions/Comparison/Selection/Select.cs @@ -586,7 +586,7 @@ public static int2 select(int2 a, int2 b, int c) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.blendv_si128(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c, MaskType.AllOnes))); + return RegisterConversion.ToInt2(Xse.blendv_si128(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c, MaskType.AllOnes))); } else { @@ -600,7 +600,7 @@ public static int3 select(int3 a, int3 b, int c) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.blendv_si128(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c, MaskType.AllOnes))); + return RegisterConversion.ToInt3(Xse.blendv_si128(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c, MaskType.AllOnes))); } else { @@ -614,7 +614,7 @@ public static int4 select(int4 a, int4 b, int c) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.blendv_si128(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c))); + return RegisterConversion.ToInt4(Xse.blendv_si128(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c))); } else { @@ -795,11 +795,11 @@ public static double2 select(double2 a, double2 b, int c) { if (Sse4_1.IsSse41Supported) { - return RegisterConversion.ToType(Sse4_1.blendv_pd(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi64(c, MaskType.SignBit))); + return RegisterConversion.ToDouble2(Sse4_1.blendv_pd(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi64(c, MaskType.SignBit))); } else if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.blendv_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi64(c))); + return RegisterConversion.ToDouble2(Xse.blendv_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi64(c))); } else { @@ -813,7 +813,7 @@ public static double3 select(double3 a, double3 b, int c) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx.mm256_blendv_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), Xse.mm256_broadcastmask_epi64(c, MaskType.SignBit)));; + return RegisterConversion.ToDouble3(Avx.mm256_blendv_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), Xse.mm256_broadcastmask_epi64(c, MaskType.SignBit)));; } else { @@ -827,7 +827,7 @@ public static double4 select(double4 a, double4 b, int c) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx.mm256_blendv_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), Xse.mm256_broadcastmask_epi64(c, MaskType.SignBit))); + return RegisterConversion.ToDouble4(Avx.mm256_blendv_pd(RegisterConversion.ToV256(a), RegisterConversion.ToV256(b), Xse.mm256_broadcastmask_epi64(c, MaskType.SignBit))); } else { @@ -842,11 +842,11 @@ public static float2 select(float2 a, float2 b, int c) { if (Sse4_1.IsSse41Supported) { - return RegisterConversion.ToType(Sse4_1.blendv_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c, MaskType.SignBit))); + return RegisterConversion.ToFloat2(Sse4_1.blendv_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c, MaskType.SignBit))); } else if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.blendv_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c, MaskType.AllOnes))); + return RegisterConversion.ToFloat2(Xse.blendv_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c, MaskType.AllOnes))); } else { @@ -860,11 +860,11 @@ public static float3 select(float3 a, float3 b, int c) { if (Sse4_1.IsSse41Supported) { - return RegisterConversion.ToType(Sse4_1.blendv_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c, MaskType.SignBit))); + return RegisterConversion.ToFloat3(Sse4_1.blendv_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c, MaskType.SignBit))); } else if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.blendv_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c))); + return RegisterConversion.ToFloat3(Xse.blendv_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c))); } else { @@ -878,11 +878,11 @@ public static float4 select(float4 a, float4 b, int c) { if (Sse4_1.IsSse41Supported) { - return RegisterConversion.ToType(Sse4_1.blendv_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c, MaskType.SignBit))); + return RegisterConversion.ToFloat4(Sse4_1.blendv_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c, MaskType.SignBit))); } else if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.blendv_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c))); + return RegisterConversion.ToFloat4(Xse.blendv_ps(RegisterConversion.ToV128(a), RegisterConversion.ToV128(b), Xse.broadcastmask_epi32(c))); } else { diff --git a/Runtime/Math Lib/Functions/Comparison/Vector Reduction/All Different.cs b/Runtime/Math Lib/Functions/Comparison/Vector Reduction/All Different.cs index c47a3d9..e4a715b 100644 --- a/Runtime/Math Lib/Functions/Comparison/Vector Reduction/All Different.cs +++ b/Runtime/Math Lib/Functions/Comparison/Vector Reduction/All Different.cs @@ -925,7 +925,7 @@ public static bool all_dif(short8 c) { finalCmp = Sse2.bsrli_si128(c, 4 * sizeof(short)); finalCmp = Sse2.or_si128(finalCmp, Sse2.bslli_si128(c, 5 * sizeof(short))); - finalCmp = Sse2.insert_epi16(finalCmp, Sse2.extract_epi16(c, 7), 5); + finalCmp = Xse.insert_epi16(finalCmp, Xse.extract_epi16(c, 7), 5); } v128 or = Sse2.or_si128(Sse2.or_si128(Sse2.cmpeq_epi16(c, Xse.bror_si128(c, 1 * sizeof(short))), @@ -1443,7 +1443,7 @@ public static bool all_dif(float8 c) } - /// Returns if all of the components of a are unique within that vector. + /// Returns if all of the components of a are unique within that vector. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool all_dif(double2 c) { @@ -1459,14 +1459,14 @@ public static bool all_dif(double2 c) } } - /// Returns if all of the components of a are unique within that vector. + /// Returns if all of the components of a are unique within that vector. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool all_dif(double3 c) { return all_dif(c.xxzx, c.yzyy); } - /// Returns if all of the components of a are unique within that vector. + /// Returns if all of the components of a are unique within that vector. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool all_dif(double4 c) { diff --git a/Runtime/Math Lib/Functions/Comparison/Vector Reduction/Column Max Magnitude.cs b/Runtime/Math Lib/Functions/Comparison/Vector Reduction/Column Max Magnitude.cs index 8b1fbea..b782078 100644 --- a/Runtime/Math Lib/Functions/Comparison/Vector Reduction/Column Max Magnitude.cs +++ b/Runtime/Math Lib/Functions/Comparison/Vector Reduction/Column Max Magnitude.cs @@ -229,7 +229,7 @@ public static short cmaxmag(short16 c) } - /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. /// A '' with its flag set returns undefined results for any cmin() + cmax() that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int cmaxmag(int2 c, Promise noOverflow = Promise.Nothing) @@ -248,7 +248,7 @@ public static int cmaxmag(int2 c, Promise noOverflow = Promise.Nothing) } } - /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. /// A '' with its flag set returns undefined results for any cmin() + cmax() that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int cmaxmag(int3 c, Promise noOverflow = Promise.Nothing) @@ -267,7 +267,7 @@ public static int cmaxmag(int3 c, Promise noOverflow = Promise.Nothing) } } - /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. /// A '' with its flag set returns undefined results for any cmin() + cmax() that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int cmaxmag(int4 c, Promise noOverflow = Promise.Nothing) @@ -344,7 +344,7 @@ public static long cmaxmag(long4 c) } - /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float cmaxmag(float2 c) { @@ -362,7 +362,7 @@ public static float cmaxmag(float2 c) } } - /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float cmaxmag(float3 c) { @@ -380,7 +380,7 @@ public static float cmaxmag(float3 c) } } - /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float cmaxmag(float4 c) { @@ -408,7 +408,7 @@ public static float cmaxmag(float8 c) } - /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double cmaxmag(double2 c) { @@ -426,7 +426,7 @@ public static double cmaxmag(double2 c) } } - /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double cmaxmag(double3 c) { @@ -435,7 +435,7 @@ public static double cmaxmag(double3 c) return maxmag(min, max); } - /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double cmaxmag(double4 c) { diff --git a/Runtime/Math Lib/Functions/Comparison/Vector Reduction/Column Min Magnitude.cs b/Runtime/Math Lib/Functions/Comparison/Vector Reduction/Column Min Magnitude.cs index dbd18eb..c3a6d41 100644 --- a/Runtime/Math Lib/Functions/Comparison/Vector Reduction/Column Min Magnitude.cs +++ b/Runtime/Math Lib/Functions/Comparison/Vector Reduction/Column Min Magnitude.cs @@ -229,7 +229,7 @@ public static short cminmag(short16 c) } - /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. /// A '' with its flag set returns undefined results for any cmin() + cmax() that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int cminmag(int2 c, Promise noOverflow = Promise.Nothing) @@ -248,7 +248,7 @@ public static int cminmag(int2 c, Promise noOverflow = Promise.Nothing) } } - /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. /// A '' with its flag set returns undefined results for any cmin() + cmax() that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int cminmag(int3 c, Promise noOverflow = Promise.Nothing) @@ -267,7 +267,7 @@ public static int cminmag(int3 c, Promise noOverflow = Promise.Nothing) } } - /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. /// A '' with its flag set returns undefined results for any cmin() + cmax() that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int cminmag(int4 c, Promise noOverflow = Promise.Nothing) @@ -344,7 +344,7 @@ public static long cminmag(long4 c) } - /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float cminmag(float2 c) { @@ -353,7 +353,7 @@ public static float cminmag(float2 c) return minmag(min, max); } - /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float cminmag(float3 c) { @@ -362,7 +362,7 @@ public static float cminmag(float3 c) return minmag(min, max); } - /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float cminmag(float4 c) { @@ -381,7 +381,7 @@ public static float cminmag(float8 c) } - /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double cminmag(double2 c) { @@ -390,7 +390,7 @@ public static double cminmag(double2 c) return minmag(min, max); } - /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double cminmag(double3 c) { @@ -399,7 +399,7 @@ public static double cminmag(double3 c) return minmag(min, max); } - /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. + /// Returns the horizontal minimum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return value is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double cminmag(double4 c) { diff --git a/Runtime/Math Lib/Functions/Comparison/Vector Reduction/Column Min Max Magnitude.cs b/Runtime/Math Lib/Functions/Comparison/Vector Reduction/Column Min Max Magnitude.cs index 8af60ab..a9d801a 100644 --- a/Runtime/Math Lib/Functions/Comparison/Vector Reduction/Column Min Max Magnitude.cs +++ b/Runtime/Math Lib/Functions/Comparison/Vector Reduction/Column Min Max Magnitude.cs @@ -10,7 +10,7 @@ namespace MaxMath { unsafe public static partial class maxmath { - /// Returns the horizontal minimum and the horizontal maximum of an with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of an with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(sbyte2 c, [NoAlias] out sbyte cminmag, [NoAlias] out sbyte cmaxmag) { @@ -31,7 +31,7 @@ public static void cminmaxmag(sbyte2 c, [NoAlias] out sbyte cminmag, [NoAlias] o } } - /// Returns the horizontal minimum and the horizontal maximum of an with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of an with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(sbyte3 c, [NoAlias] out sbyte cminmag, [NoAlias] out sbyte cmaxmag) { @@ -52,7 +52,7 @@ public static void cminmaxmag(sbyte3 c, [NoAlias] out sbyte cminmag, [NoAlias] o } } - /// Returns the horizontal minimum and the horizontal maximum of an with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of an with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(sbyte4 c, [NoAlias] out sbyte cminmag, [NoAlias] out sbyte cmaxmag) { @@ -73,7 +73,7 @@ public static void cminmaxmag(sbyte4 c, [NoAlias] out sbyte cminmag, [NoAlias] o } } - /// Returns the horizontal minimum and the horizontal maximum of an with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of an with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(sbyte8 c, [NoAlias] out sbyte cminmag, [NoAlias] out sbyte cmaxmag) { @@ -94,7 +94,7 @@ public static void cminmaxmag(sbyte8 c, [NoAlias] out sbyte cminmag, [NoAlias] o } } - /// Returns the horizontal minimum and the horizontal maximum of an with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of an with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(sbyte16 c, [NoAlias] out sbyte cminmag, [NoAlias] out sbyte cmaxmag) { @@ -115,7 +115,7 @@ public static void cminmaxmag(sbyte16 c, [NoAlias] out sbyte cminmag, [NoAlias] } } - /// Returns the horizontal minimum and the horizontal maximum of an with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of an with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(sbyte32 c, [NoAlias] out sbyte cminmag, [NoAlias] out sbyte cmaxmag) { @@ -151,7 +151,7 @@ public static void cminmaxmag(sbyte32 c, [NoAlias] out sbyte cminmag, [NoAlias] } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(short2 c, [NoAlias] out short cminmag, [NoAlias] out short cmaxmag) { @@ -172,7 +172,7 @@ public static void cminmaxmag(short2 c, [NoAlias] out short cminmag, [NoAlias] o } } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(short3 c, [NoAlias] out short cminmag, [NoAlias] out short cmaxmag) { @@ -193,7 +193,7 @@ public static void cminmaxmag(short3 c, [NoAlias] out short cminmag, [NoAlias] o } } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(short4 c, [NoAlias] out short cminmag, [NoAlias] out short cmaxmag) { @@ -214,7 +214,7 @@ public static void cminmaxmag(short4 c, [NoAlias] out short cminmag, [NoAlias] o } } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(short8 c, [NoAlias] out short cminmag, [NoAlias] out short cmaxmag) { @@ -235,7 +235,7 @@ public static void cminmaxmag(short8 c, [NoAlias] out short cminmag, [NoAlias] o } } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(short16 c, [NoAlias] out short cminmag, [NoAlias] out short cmaxmag) { @@ -270,7 +270,7 @@ public static void cminmaxmag(short16 c, [NoAlias] out short cminmag, [NoAlias] } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. /// A '' with its flag set returns undefined results for any cmin() + cmax() that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(int2 c, [NoAlias] out int cminmag, [NoAlias] out int cmaxmag, Promise noOverflow = Promise.Nothing) @@ -292,7 +292,7 @@ public static void cminmaxmag(int2 c, [NoAlias] out int cminmag, [NoAlias] out i } } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. /// A '' with its flag set returns undefined results for any cmin() + cmax() that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(int3 c, [NoAlias] out int cminmag, [NoAlias] out int cmaxmag, Promise noOverflow = Promise.Nothing) @@ -314,7 +314,7 @@ public static void cminmaxmag(int3 c, [NoAlias] out int cminmag, [NoAlias] out i } } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. /// A '' with its flag set returns undefined results for any cmin() + cmax() that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(int4 c, [NoAlias] out int cminmag, [NoAlias] out int cmaxmag, Promise noOverflow = Promise.Nothing) @@ -336,7 +336,7 @@ public static void cminmaxmag(int4 c, [NoAlias] out int cminmag, [NoAlias] out i } } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. /// A '' with its flag set returns undefined results for any cmin() + cmax() that overflows. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(int8 c, [NoAlias] out int cminmag, [NoAlias] out int cmaxmag, Promise noOverflow = Promise.Nothing) @@ -371,7 +371,7 @@ public static void cminmaxmag(int8 c, [NoAlias] out int cminmag, [NoAlias] out i } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(long2 c, [NoAlias] out long cminmag, [NoAlias] out long cmaxmag) { @@ -381,7 +381,7 @@ public static void cminmaxmag(long2 c, [NoAlias] out long cminmag, [NoAlias] out cmaxmag = maxmag(min, max); } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(long3 c, [NoAlias] out long cminmag, [NoAlias] out long cmaxmag) { @@ -391,7 +391,7 @@ public static void cminmaxmag(long3 c, [NoAlias] out long cminmag, [NoAlias] out cmaxmag = maxmag(min, max); } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(long4 c, [NoAlias] out long cminmag, [NoAlias] out long cmaxmag) { @@ -402,7 +402,7 @@ public static void cminmaxmag(long4 c, [NoAlias] out long cminmag, [NoAlias] out } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(float2 c, [NoAlias] out float cminmag, [NoAlias] out float cmaxmag) { @@ -423,7 +423,7 @@ public static void cminmaxmag(float2 c, [NoAlias] out float cminmag, [NoAlias] o } } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(float3 c, [NoAlias] out float cminmag, [NoAlias] out float cmaxmag) { @@ -444,7 +444,7 @@ public static void cminmaxmag(float3 c, [NoAlias] out float cminmag, [NoAlias] o } } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(float4 c, [NoAlias] out float cminmag, [NoAlias] out float cmaxmag) { @@ -465,7 +465,7 @@ public static void cminmaxmag(float4 c, [NoAlias] out float cminmag, [NoAlias] o } } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(float8 c, [NoAlias] out float cminmag, [NoAlias] out float cmaxmag) { @@ -476,7 +476,7 @@ public static void cminmaxmag(float8 c, [NoAlias] out float cminmag, [NoAlias] o } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(double2 c, [NoAlias] out double cminmag, [NoAlias] out double cmaxmag) { @@ -497,7 +497,7 @@ public static void cminmaxmag(double2 c, [NoAlias] out double cminmag, [NoAlias] } } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(double3 c, [NoAlias] out double cminmag, [NoAlias] out double cmaxmag) { @@ -507,7 +507,7 @@ public static void cminmaxmag(double3 c, [NoAlias] out double cminmag, [NoAlias] cmaxmag = maxmag(min, max); } - /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the cmaxmag = value is undefined. + /// Returns the horizontal minimum and the horizontal maximum of a with regard to magnitude. If abs(cmin()) is equal to abs(cmax()), the sign of the return values is undefined. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmaxmag(double4 c, [NoAlias] out double cminmag, [NoAlias] out double cmaxmag) { diff --git a/Runtime/Math Lib/Functions/Comparison/Vector Reduction/Column Min Max.cs b/Runtime/Math Lib/Functions/Comparison/Vector Reduction/Column Min Max.cs index 5bb5ae8..882bbd5 100644 --- a/Runtime/Math Lib/Functions/Comparison/Vector Reduction/Column Min Max.cs +++ b/Runtime/Math Lib/Functions/Comparison/Vector Reduction/Column Min Max.cs @@ -1148,7 +1148,7 @@ public static void cminmax(float8 a, [NoAlias] out float min, [NoAlias] out floa } - /// Returns the horizontal minimum '' and maximum '' of two s. + /// Returns the horizontal minimum '' and maximum '' of two s. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmax(double2 a, [NoAlias] out double min, [NoAlias] out double max) { @@ -1165,7 +1165,7 @@ public static void cminmax(double2 a, [NoAlias] out double min, [NoAlias] out do } } - /// Returns the horizontal minimum '' and maximum '' of two s. + /// Returns the horizontal minimum '' and maximum '' of two s. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmax(double3 a, [NoAlias] out double min, [NoAlias] out double max) { @@ -1175,7 +1175,7 @@ public static void cminmax(double3 a, [NoAlias] out double min, [NoAlias] out do max = math.max(maxLo, a.z); } - /// Returns the horizontal minimum '' and maximum '' of two s. + /// Returns the horizontal minimum '' and maximum '' of two s. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void cminmax(double4 a, [NoAlias] out double min, [NoAlias] out double max) { diff --git a/Runtime/Math Lib/Functions/Interpolation/Cubic.cs b/Runtime/Math Lib/Functions/Interpolation/Cubic.cs index 4c7202b..d4ae61b 100644 --- a/Runtime/Math Lib/Functions/Interpolation/Cubic.cs +++ b/Runtime/Math Lib/Functions/Interpolation/Cubic.cs @@ -1,6 +1,5 @@ using System.Runtime.CompilerServices; using Unity.Mathematics; -using DevTools; namespace MaxMath { diff --git a/Runtime/Math Lib/Functions/Shuffles/Vector Rotate.cs b/Runtime/Math Lib/Functions/Shuffles/Vector Rotate.cs index c1ab123..ef76334 100644 --- a/Runtime/Math Lib/Functions/Shuffles/Vector Rotate.cs +++ b/Runtime/Math Lib/Functions/Shuffles/Vector Rotate.cs @@ -5,7 +5,7 @@ using MaxMath.Intrinsics; using static Unity.Burst.Intrinsics.X86; - + namespace MaxMath { namespace Intrinsics @@ -660,7 +660,7 @@ public static int4 vror(int4 x, int n) stack[0] = RegisterConversion.ToV128(x); stack[1] = RegisterConversion.ToV128(x); - return RegisterConversion.ToType(Sse2.loadu_si128((byte*)stack + (((uint)n % 4) * sizeof(int)))); + return RegisterConversion.ToInt4(Sse2.loadu_si128((byte*)stack + (((uint)n % 4) * sizeof(int)))); } switch ((uint)n % 4) @@ -703,7 +703,7 @@ public static int8 vror(int8 x, int n) v128 lo = Sse2.loadu_si128(address); v128 hi = Sse2.loadu_si128(address + sizeof(v128)); - return new int8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + return new int8(RegisterConversion.ToInt4(lo), RegisterConversion.ToInt4(hi)); } switch ((uint)n % 8) @@ -1027,7 +1027,7 @@ public static double4 vror(double4 x, int n) stack[0] = RegisterConversion.ToV256(x); stack[1] = RegisterConversion.ToV256(x); - return RegisterConversion.ToType(Avx.mm256_loadu_pd((byte*)stack + (((uint)n % 4) * sizeof(double)))); + return RegisterConversion.ToDouble4(Avx.mm256_loadu_pd((byte*)stack + (((uint)n % 4) * sizeof(double)))); } else if (Sse.IsSseSupported) { @@ -1042,7 +1042,7 @@ public static double4 vror(double4 x, int n) v128 lo = Sse.loadu_ps(address); v128 hi = Sse.loadu_ps(address + sizeof(v128)); - return new double4(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + return new double4(RegisterConversion.ToDouble2(lo), RegisterConversion.ToDouble2(hi)); } switch ((uint)n % 4) @@ -1753,7 +1753,7 @@ public static int4 vrol(int4 x, int n) stack[0] = RegisterConversion.ToV128(x); stack[1] = RegisterConversion.ToV128(x); - return RegisterConversion.ToType(Sse2.loadu_si128((byte*)stack + ((4 - ((uint)n % 4)) * sizeof(int)))); + return RegisterConversion.ToInt4(Sse2.loadu_si128((byte*)stack + ((4 - ((uint)n % 4)) * sizeof(int)))); } switch ((uint)n % 4) @@ -1794,7 +1794,7 @@ public static int8 vrol(int8 x, int n) v128 lo = Sse2.loadu_si128(address); v128 hi = Sse2.loadu_si128(address + sizeof(v128)); - return new int8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + return new int8(RegisterConversion.ToInt4(lo), RegisterConversion.ToInt4(hi)); } } @@ -2153,7 +2153,7 @@ public static double4 vrol(double4 x, int n) stack[0] = RegisterConversion.ToV256(x); stack[1] = RegisterConversion.ToV256(x); - return RegisterConversion.ToType(Avx.mm256_loadu_pd((byte*)stack + ((4 - ((uint)n % 4)) * sizeof(double)))); + return RegisterConversion.ToDouble4(Avx.mm256_loadu_pd((byte*)stack + ((4 - ((uint)n % 4)) * sizeof(double)))); } else if (Sse.IsSseSupported) { @@ -2168,7 +2168,7 @@ public static double4 vrol(double4 x, int n) v128 lo = Sse.loadu_ps(address); v128 hi = Sse.loadu_ps(address + sizeof(v128)); - return new double4(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + return new double4(RegisterConversion.ToDouble2(lo), RegisterConversion.ToDouble2(hi)); } switch ((uint)n % 4) diff --git a/Runtime/Math Lib/Functions/Shuffles/Vector Shifts.cs b/Runtime/Math Lib/Functions/Shuffles/Vector Shifts.cs index 00df9f9..a255628 100644 --- a/Runtime/Math Lib/Functions/Shuffles/Vector Shifts.cs +++ b/Runtime/Math Lib/Functions/Shuffles/Vector Shifts.cs @@ -186,7 +186,7 @@ public static int2 vshl(int2 x, int n) { switch (n) { - case 1: return RegisterConversion.ToType(Sse2.bslli_si128(RegisterConversion.ToV128(x), sizeof(int))); + case 1: return RegisterConversion.ToInt2(Sse2.bslli_si128(RegisterConversion.ToV128(x), sizeof(int))); default: return x; } @@ -210,8 +210,8 @@ public static int3 vshl(int3 x, int n) { switch (n) { - case 1: return RegisterConversion.ToType(Sse2.bslli_si128(RegisterConversion.ToV128(x), sizeof(int))); - case 2: return RegisterConversion.ToType(Sse2.bslli_si128(RegisterConversion.ToV128(x), 2 * sizeof(int))); + case 1: return RegisterConversion.ToInt3(Sse2.bslli_si128(RegisterConversion.ToV128(x), sizeof(int))); + case 2: return RegisterConversion.ToInt3(Sse2.bslli_si128(RegisterConversion.ToV128(x), 2 * sizeof(int))); default: return x; } @@ -239,9 +239,9 @@ public static int4 vshl(int4 x, int n) { switch (n) { - case 1: return RegisterConversion.ToType(Sse2.bslli_si128(RegisterConversion.ToV128(x), sizeof(int))); - case 2: return RegisterConversion.ToType(Sse2.bslli_si128(RegisterConversion.ToV128(x), 2 * sizeof(int))); - case 3: return RegisterConversion.ToType(Sse2.bslli_si128(RegisterConversion.ToV128(x), 3 * sizeof(int))); + case 1: return RegisterConversion.ToInt4(Sse2.bslli_si128(RegisterConversion.ToV128(x), sizeof(int))); + case 2: return RegisterConversion.ToInt4(Sse2.bslli_si128(RegisterConversion.ToV128(x), 2 * sizeof(int))); + case 3: return RegisterConversion.ToInt4(Sse2.bslli_si128(RegisterConversion.ToV128(x), 3 * sizeof(int))); default: return x; } @@ -253,7 +253,7 @@ public static int4 vshl(int4 x, int n) stack[0] = Sse2.setzero_si128(); stack[1] = RegisterConversion.ToV128(x); - return RegisterConversion.ToType(Sse2.loadu_si128((byte*)stack + (sizeof(v128) - (((uint)n % 4) * sizeof(int))))); + return RegisterConversion.ToInt4(Sse2.loadu_si128((byte*)stack + (sizeof(v128) - (((uint)n % 4) * sizeof(int))))); } } else @@ -288,34 +288,34 @@ public static int8 vshl(int8 x, int n) { v128 lo = Sse2.bslli_si128(RegisterConversion.ToV128(x._v4_0), 1 * sizeof(int)); - return new int8(RegisterConversion.ToType(lo), math.shuffle(x._v4_0, x._v4_4, math.ShuffleComponent.LeftW, math.ShuffleComponent.RightX, math.ShuffleComponent.RightY, math.ShuffleComponent.RightZ)); + return new int8(RegisterConversion.ToInt4(lo), math.shuffle(x._v4_0, x._v4_4, math.ShuffleComponent.LeftW, math.ShuffleComponent.RightX, math.ShuffleComponent.RightY, math.ShuffleComponent.RightZ)); } case 2: { v128 lo = Sse2.bslli_si128(RegisterConversion.ToV128(x._v4_0), 2 * sizeof(int)); - return new int8(RegisterConversion.ToType(lo), math.shuffle(x._v4_0, x._v4_4, math.ShuffleComponent.LeftZ, math.ShuffleComponent.LeftW, math.ShuffleComponent.RightX, math.ShuffleComponent.RightY)); + return new int8(RegisterConversion.ToInt4(lo), math.shuffle(x._v4_0, x._v4_4, math.ShuffleComponent.LeftZ, math.ShuffleComponent.LeftW, math.ShuffleComponent.RightX, math.ShuffleComponent.RightY)); } case 3: { v128 lo = Sse2.bslli_si128(RegisterConversion.ToV128(x._v4_0), 3 * sizeof(int)); - return new int8(RegisterConversion.ToType(lo), math.shuffle(x._v4_0, x._v4_4, math.ShuffleComponent.LeftY, math.ShuffleComponent.LeftZ, math.ShuffleComponent.LeftW, math.ShuffleComponent.RightX)); + return new int8(RegisterConversion.ToInt4(lo), math.shuffle(x._v4_0, x._v4_4, math.ShuffleComponent.LeftY, math.ShuffleComponent.LeftZ, math.ShuffleComponent.LeftW, math.ShuffleComponent.RightX)); } case 4: return new int8(int4.zero, x._v4_0); case 5: { - return new int8(int4.zero, RegisterConversion.ToType(Sse2.bslli_si128(RegisterConversion.ToV128(x._v4_0), 1 * sizeof(int)))); + return new int8(int4.zero, RegisterConversion.ToInt4(Sse2.bslli_si128(RegisterConversion.ToV128(x._v4_0), 1 * sizeof(int)))); } case 6: { - return new int8(int4.zero, RegisterConversion.ToType(Sse2.bslli_si128(RegisterConversion.ToV128(x._v4_0), 2 * sizeof(int)))); + return new int8(int4.zero, RegisterConversion.ToInt4(Sse2.bslli_si128(RegisterConversion.ToV128(x._v4_0), 2 * sizeof(int)))); } case 7: { - return new int8(int4.zero, RegisterConversion.ToType(Sse2.bslli_si128(RegisterConversion.ToV128(x._v4_0), 3 * sizeof(int)))); + return new int8(int4.zero, RegisterConversion.ToInt4(Sse2.bslli_si128(RegisterConversion.ToV128(x._v4_0), 3 * sizeof(int)))); } default: return x; @@ -337,7 +337,7 @@ public static int8 vshl(int8 x, int n) v128 lo = Sse2.loadu_si128(address); v128 hi = Sse2.loadu_si128(address + 1); - return new int8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + return new int8(RegisterConversion.ToInt4(lo), RegisterConversion.ToInt4(hi)); } } else @@ -1441,7 +1441,7 @@ public static int2 vshr(int2 x, int n) { switch (n) { - case 1: return RegisterConversion.ToType(Sse2.bsrli_si128(Sse2.bslli_si128(RegisterConversion.ToV128(x), 2 * sizeof(int)), 3 * sizeof(int))); + case 1: return RegisterConversion.ToInt2(Sse2.bsrli_si128(Sse2.bslli_si128(RegisterConversion.ToV128(x), 2 * sizeof(int)), 3 * sizeof(int))); default: return x; } @@ -1465,8 +1465,8 @@ public static int3 vshr(int3 x, int n) { switch (n) { - case 1: return RegisterConversion.ToType(Sse2.bsrli_si128(Sse2.bslli_si128(RegisterConversion.ToV128(x), 1 * sizeof(int)), 2 * sizeof(int))); - case 2: return RegisterConversion.ToType(Sse2.bsrli_si128(Sse2.bslli_si128(RegisterConversion.ToV128(x), 1 * sizeof(int)), 3 * sizeof(int))); + case 1: return RegisterConversion.ToInt3(Sse2.bsrli_si128(Sse2.bslli_si128(RegisterConversion.ToV128(x), 1 * sizeof(int)), 2 * sizeof(int))); + case 2: return RegisterConversion.ToInt3(Sse2.bsrli_si128(Sse2.bslli_si128(RegisterConversion.ToV128(x), 1 * sizeof(int)), 3 * sizeof(int))); default: return x; } @@ -1494,9 +1494,9 @@ public static int4 vshr(int4 x, int n) { switch (n) { - case 1: return RegisterConversion.ToType(Sse2.bsrli_si128(RegisterConversion.ToV128(x), sizeof(int))); - case 2: return RegisterConversion.ToType(Sse2.bsrli_si128(RegisterConversion.ToV128(x), 2 * sizeof(int))); - case 3: return RegisterConversion.ToType(Sse2.bsrli_si128(RegisterConversion.ToV128(x), 3 * sizeof(int))); + case 1: return RegisterConversion.ToInt4(Sse2.bsrli_si128(RegisterConversion.ToV128(x), sizeof(int))); + case 2: return RegisterConversion.ToInt4(Sse2.bsrli_si128(RegisterConversion.ToV128(x), 2 * sizeof(int))); + case 3: return RegisterConversion.ToInt4(Sse2.bsrli_si128(RegisterConversion.ToV128(x), 3 * sizeof(int))); default: return x; } @@ -1508,7 +1508,7 @@ public static int4 vshr(int4 x, int n) stack[0] = RegisterConversion.ToV128(x); stack[1] = Sse2.setzero_si128(); - return RegisterConversion.ToType(Sse2.loadu_si128((byte*)stack + (((uint)n % 4) * sizeof(int)))); + return RegisterConversion.ToInt4(Sse2.loadu_si128((byte*)stack + (((uint)n % 4) * sizeof(int)))); } } else @@ -1543,19 +1543,19 @@ public static int8 vshr(int8 x, int n) { v128 hi = Sse2.bsrli_si128(RegisterConversion.ToV128(x._v4_4), 1 * sizeof(int)); - return new int8(math.shuffle(x._v4_0, x._v4_4, math.ShuffleComponent.LeftY, math.ShuffleComponent.LeftZ, math.ShuffleComponent.LeftW, math.ShuffleComponent.RightX), RegisterConversion.ToType(hi)); + return new int8(math.shuffle(x._v4_0, x._v4_4, math.ShuffleComponent.LeftY, math.ShuffleComponent.LeftZ, math.ShuffleComponent.LeftW, math.ShuffleComponent.RightX), RegisterConversion.ToInt4(hi)); } case 2: { v128 hi = Sse2.bsrli_si128(RegisterConversion.ToV128(x._v4_4), 2 * sizeof(int)); - return new int8(math.shuffle(x._v4_0, x._v4_4, math.ShuffleComponent.LeftZ, math.ShuffleComponent.LeftW, math.ShuffleComponent.RightX, math.ShuffleComponent.RightY), RegisterConversion.ToType(hi)); + return new int8(math.shuffle(x._v4_0, x._v4_4, math.ShuffleComponent.LeftZ, math.ShuffleComponent.LeftW, math.ShuffleComponent.RightX, math.ShuffleComponent.RightY), RegisterConversion.ToInt4(hi)); } case 3: { v128 hi = Sse2.bsrli_si128(RegisterConversion.ToV128(x._v4_4), 3 * sizeof(int)); - return new int8(math.shuffle(x._v4_0, x._v4_4, math.ShuffleComponent.LeftW, math.ShuffleComponent.RightX, math.ShuffleComponent.RightY, math.ShuffleComponent.RightZ), RegisterConversion.ToType(hi)); + return new int8(math.shuffle(x._v4_0, x._v4_4, math.ShuffleComponent.LeftW, math.ShuffleComponent.RightX, math.ShuffleComponent.RightY, math.ShuffleComponent.RightZ), RegisterConversion.ToInt4(hi)); } case 4: return new int8(x._v4_4, int4.zero); @@ -1564,22 +1564,22 @@ public static int8 vshr(int8 x, int n) { v128 lo = Sse2.bsrli_si128(RegisterConversion.ToV128(x._v4_4), 1 * sizeof(int)); - return new int8(RegisterConversion.ToType(lo), int4.zero); + return new int8(RegisterConversion.ToInt4(lo), int4.zero); } case 6: { v128 lo = Sse2.bsrli_si128(RegisterConversion.ToV128(x._v4_4), 2 * sizeof(int)); - return new int8(RegisterConversion.ToType(lo), int4.zero); + return new int8(RegisterConversion.ToInt4(lo), int4.zero); } case 7: { v128 lo = Sse2.bsrli_si128(RegisterConversion.ToV128(x._v4_4), 3 * sizeof(int)); - return new int8(RegisterConversion.ToType(lo), int4.zero); + return new int8(RegisterConversion.ToInt4(lo), int4.zero); } - default: { v128 zero = Sse2.setzero_si128(); return new int8(RegisterConversion.ToType(zero), RegisterConversion.ToType(zero)); } + default: { v128 zero = Sse2.setzero_si128(); return new int8(RegisterConversion.ToInt4(zero), RegisterConversion.ToInt4(zero)); } } } else @@ -1598,7 +1598,7 @@ public static int8 vshr(int8 x, int n) v128 lo = Sse2.loadu_si128(address); v128 hi = Sse2.loadu_si128(address + 1); - return new int8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + return new int8(RegisterConversion.ToInt4(lo), RegisterConversion.ToInt4(hi)); } } else diff --git a/Runtime/Math Lib/Functions/Special Functions/Error Function.cs b/Runtime/Math Lib/Functions/Special Functions/Error Function.cs index dc16329..6bf70ad 100644 --- a/Runtime/Math Lib/Functions/Special Functions/Error Function.cs +++ b/Runtime/Math Lib/Functions/Special Functions/Error Function.cs @@ -9,9 +9,9 @@ namespace MaxMath { - namespace Intrinsics - { - unsafe public static partial class Xse + namespace Intrinsics + { + unsafe public static partial class Xse { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v128 erf_ps(v128 a, byte elements = 4) @@ -87,7 +87,7 @@ public static v128 erf_ps(v128 a, byte elements = 4) v128 bound5Mask = Sse2.cmpgt_epi32(Sse2.set1_epi32(0x4036_DB6D), abs); v128 exp0 = fnmadd_ps(abs, abs, Sse.set1_ps(-0.5625f)); v128 mulExp1 = Sse.mul_ps(Sse.sub_ps(abs, absA), Sse.add_ps(abs, absA)); - v128 result5 = default; + v128 result5; if (elements > 2) { @@ -1152,7 +1152,7 @@ public static float2 erf(float2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.erf_ps(RegisterConversion.ToV128(x), 2)); + return RegisterConversion.ToFloat2(Xse.erf_ps(RegisterConversion.ToV128(x), 2)); } else { @@ -1166,7 +1166,7 @@ public static float3 erf(float3 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.erf_ps(RegisterConversion.ToV128(x), 3)); + return RegisterConversion.ToFloat3(Xse.erf_ps(RegisterConversion.ToV128(x), 3)); } else { @@ -1180,7 +1180,7 @@ public static float4 erf(float4 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.erf_ps(RegisterConversion.ToV128(x), 4)); + return RegisterConversion.ToFloat4(Xse.erf_ps(RegisterConversion.ToV128(x), 4)); } else { @@ -1283,7 +1283,7 @@ public static double2 erf(double2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.erf_pd(RegisterConversion.ToV128(x))); + return RegisterConversion.ToDouble2(Xse.erf_pd(RegisterConversion.ToV128(x))); } else { @@ -1297,7 +1297,7 @@ public static double3 erf(double3 x) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_erf_pd(RegisterConversion.ToV256(x), 3)); + return RegisterConversion.ToDouble3(Xse.mm256_erf_pd(RegisterConversion.ToV256(x), 3)); } else { @@ -1311,7 +1311,7 @@ public static double4 erf(double4 x) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_erf_pd(RegisterConversion.ToV256(x), 4)); + return RegisterConversion.ToDouble4(Xse.mm256_erf_pd(RegisterConversion.ToV256(x), 4)); } else { @@ -1397,7 +1397,7 @@ public static float2 erfc(float2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.erfc_ps(RegisterConversion.ToV128(x), 2)); + return RegisterConversion.ToFloat2(Xse.erfc_ps(RegisterConversion.ToV128(x), 2)); } else { @@ -1411,7 +1411,7 @@ public static float3 erfc(float3 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.erfc_ps(RegisterConversion.ToV128(x), 3)); + return RegisterConversion.ToFloat3(Xse.erfc_ps(RegisterConversion.ToV128(x), 3)); } else { @@ -1425,7 +1425,7 @@ public static float4 erfc(float4 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.erfc_ps(RegisterConversion.ToV128(x), 4)); + return RegisterConversion.ToFloat4(Xse.erfc_ps(RegisterConversion.ToV128(x), 4)); } else { @@ -1526,7 +1526,7 @@ public static double2 erfc(double2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.erfc_pd(RegisterConversion.ToV128(x))); + return RegisterConversion.ToDouble2(Xse.erfc_pd(RegisterConversion.ToV128(x))); } else { @@ -1540,7 +1540,7 @@ public static double3 erfc(double3 x) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_erfc_pd(RegisterConversion.ToV256(x), 3)); + return RegisterConversion.ToDouble3(Xse.mm256_erfc_pd(RegisterConversion.ToV256(x), 3)); } else { @@ -1554,7 +1554,7 @@ public static double4 erfc(double4 x) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_erfc_pd(RegisterConversion.ToV256(x), 4)); + return RegisterConversion.ToDouble4(Xse.mm256_erfc_pd(RegisterConversion.ToV256(x), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Special Functions/Gamma Function.cs b/Runtime/Math Lib/Functions/Special Functions/Gamma Function.cs index 2ab908f..ee16b5e 100644 --- a/Runtime/Math Lib/Functions/Special Functions/Gamma Function.cs +++ b/Runtime/Math Lib/Functions/Special Functions/Gamma Function.cs @@ -1,6 +1,5 @@ using System.Runtime.CompilerServices; using Unity.Mathematics; -using Unity.Burst.CompilerServices; using Unity.Burst.Intrinsics; using MaxMath.Intrinsics; @@ -9,9 +8,9 @@ namespace MaxMath { - namespace Intrinsics - { - unsafe public static partial class Xse + namespace Intrinsics + { + unsafe public static partial class Xse { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v128 gamma_ps(v128 a, byte elements = 4) @@ -57,7 +56,7 @@ public static v128 gamma_ps(v128 a, byte elements = 4) v128 y = Sse.add_ps(absX, Sse.set1_ps((float)GM_HALF)); v128 z = Sse.sub_ps(absX, HALF); - v128 r = Sse.mul_ps(Sse.div_ps(num, den), RegisterConversion.ToV128(math.exp(-RegisterConversion.ToType(y)))); + v128 r = Sse.mul_ps(Sse.div_ps(num, den), RegisterConversion.ToV128(math.exp(-RegisterConversion.ToFloat4(y)))); bool reflect; if (elements == 2) reflect = (Sse.movemask_ps(a) & 0b0011) != 0; @@ -74,7 +73,7 @@ public static v128 gamma_ps(v128 a, byte elements = 4) } else { - floorsinpi = RegisterConversion.ToV128(math.floor(RegisterConversion.ToType(sinpi))); + floorsinpi = RegisterConversion.ToV128(math.floor(RegisterConversion.ToFloat4(sinpi))); } sinpi = Sse.sub_ps(sinpi, floorsinpi); sinpi = Sse.add_ps(sinpi, sinpi); @@ -88,14 +87,14 @@ public static v128 gamma_ps(v128 a, byte elements = 4) sinpi = fnmadd_ps(Sse2.cvtepi32_ps(n), HALF, sinpi); sinpi = fmadd_ps(sinpi, PI, ternarylogic_si128(PI, q1, q3, TernaryOperation.OxEO)); sinpi = ternarylogic_si128(ABS_MASK, q2, sinpi, TernaryOperation.OxA6); - sinpi = RegisterConversion.ToV128(math.sin(RegisterConversion.ToType(sinpi))); + sinpi = RegisterConversion.ToV128(math.sin(RegisterConversion.ToFloat4(sinpi))); sinpi = ternarylogic_si128(ABS_MASK, q3, sinpi, TernaryOperation.OxA6); r = Sse.div_ps(Sse.set1_ps(-math.PI), Sse.mul_ps(sinpi, Sse.mul_ps(absX, r))); z = ternarylogic_si128(ABS_MASK, a, z, TernaryOperation.OxA6); } - v128 result = Sse.mul_ps(r, RegisterConversion.ToV128(math.pow(RegisterConversion.ToType(y), RegisterConversion.ToType(z)))); + v128 result = Sse.mul_ps(r, RegisterConversion.ToV128(math.pow(RegisterConversion.ToFloat4(y), RegisterConversion.ToFloat4(z)))); // the following is 100% free, ILP v128 negative; @@ -109,8 +108,8 @@ public static v128 gamma_ps(v128 a, byte elements = 4) } else { - floorX = RegisterConversion.ToV128(math.floor(RegisterConversion.ToType(a))); - floorHalfX = RegisterConversion.ToV128(math.floor(RegisterConversion.ToType(HALF) * RegisterConversion.ToType(a))); + floorX = RegisterConversion.ToV128(math.floor(RegisterConversion.ToFloat4(a))); + floorHalfX = RegisterConversion.ToV128(math.floor(RegisterConversion.ToFloat4(HALF) * RegisterConversion.ToFloat4(a))); negative = Sse2.srai_epi32(a, 31); } @@ -284,7 +283,7 @@ public static v128 gamma_pd(v128 a) v128 y = Sse2.add_pd(absX, Sse2.set1_pd(GM_HALF)); v128 z = Sse2.sub_pd(absX, HALF); - v128 r = Sse2.mul_pd(Sse2.div_pd(num, den), RegisterConversion.ToV128(math.exp(-RegisterConversion.ToType(y)))); + v128 r = Sse2.mul_pd(Sse2.div_pd(num, den), RegisterConversion.ToV128(math.exp(-RegisterConversion.ToDouble2(y)))); if (Sse2.movemask_pd(a) != 0) { @@ -296,7 +295,7 @@ public static v128 gamma_pd(v128 a) } else { - floorsinpi = RegisterConversion.ToV128(math.floor(RegisterConversion.ToType(sinpi))); + floorsinpi = RegisterConversion.ToV128(math.floor(RegisterConversion.ToDouble2(sinpi))); } sinpi = Sse2.sub_pd(sinpi, floorsinpi); sinpi = Sse2.add_pd(sinpi, sinpi); @@ -320,14 +319,14 @@ public static v128 gamma_pd(v128 a) sinpi = fnmadd_pd(usfcvtepu64_pd(n), HALF, sinpi); sinpi = fmadd_pd(sinpi, PI, ternarylogic_si128(PI, q1, q3, TernaryOperation.OxEO)); sinpi = ternarylogic_si128(ABS_MASK, q2, sinpi, TernaryOperation.OxA6); - sinpi = RegisterConversion.ToV128(math.sin(RegisterConversion.ToType(sinpi))); + sinpi = RegisterConversion.ToV128(math.sin(RegisterConversion.ToDouble2(sinpi))); sinpi = ternarylogic_si128(ABS_MASK, q3, sinpi, TernaryOperation.OxA6); r = Sse2.div_pd(Sse2.set1_pd(-math.PI_DBL), Sse2.mul_pd(sinpi, Sse2.mul_pd(absX, r))); z = ternarylogic_si128(ABS_MASK, a, z, TernaryOperation.OxA6); } - v128 result = Sse2.mul_pd(r, RegisterConversion.ToV128(math.pow(RegisterConversion.ToType(y), RegisterConversion.ToType(z)))); + v128 result = Sse2.mul_pd(r, RegisterConversion.ToV128(math.pow(RegisterConversion.ToDouble2(y), RegisterConversion.ToDouble2(z)))); v128 negative = Sse2.andnot_pd(ABS_MASK, a); v128 floorX; @@ -339,8 +338,8 @@ public static v128 gamma_pd(v128 a) } else { - floorX = RegisterConversion.ToV128(math.floor(RegisterConversion.ToType(a))); - floorHalfX = RegisterConversion.ToV128(math.floor(RegisterConversion.ToType(HALF) * RegisterConversion.ToType(a))); + floorX = RegisterConversion.ToV128(math.floor(RegisterConversion.ToDouble2(a))); + floorHalfX = RegisterConversion.ToV128(math.floor(RegisterConversion.ToDouble2(HALF) * RegisterConversion.ToDouble2(a))); negative = srai_epi64(negative, 63); } @@ -425,7 +424,7 @@ public static v256 mm256_gamma_pd(v256 a, byte elements = 4) v256 y = Avx.mm256_add_pd(absX, Avx.mm256_set1_pd(GM_HALF)); v256 z = Avx.mm256_sub_pd(absX, HALF); - v256 r = Avx.mm256_mul_pd(Avx.mm256_div_pd(num, den), RegisterConversion.ToV256(math.exp(-RegisterConversion.ToType(y)))); + v256 r = Avx.mm256_mul_pd(Avx.mm256_div_pd(num, den), RegisterConversion.ToV256(math.exp(-RegisterConversion.ToDouble4(y)))); bool reflect; if (elements == 3) reflect = (Avx.mm256_movemask_pd(a) & 0b0111) != 0; @@ -447,14 +446,14 @@ public static v256 mm256_gamma_pd(v256 a, byte elements = 4) sinpi = mm256_fnmadd_pd(mm256_usfcvtepu64_pd(n), HALF, sinpi); sinpi = mm256_fmadd_pd(sinpi, PI, mm256_ternarylogic_si256(PI, q1, q3, TernaryOperation.OxEO)); sinpi = mm256_ternarylogic_si256(ABS_MASK, q2, sinpi, TernaryOperation.OxA6); - sinpi = RegisterConversion.ToV256(math.sin(RegisterConversion.ToType(sinpi))); + sinpi = RegisterConversion.ToV256(math.sin(RegisterConversion.ToDouble4(sinpi))); sinpi = mm256_ternarylogic_si256(ABS_MASK, q3, sinpi, TernaryOperation.OxA6); r = Avx.mm256_div_pd(Avx.mm256_set1_pd(-math.PI_DBL), Avx.mm256_mul_pd(sinpi, Avx.mm256_mul_pd(absX, r))); z = mm256_ternarylogic_si256(ABS_MASK, a, z, TernaryOperation.OxA6); } - v256 result = Avx.mm256_mul_pd(r, RegisterConversion.ToV256(math.pow(RegisterConversion.ToType(y), RegisterConversion.ToType(z)))); + v256 result = Avx.mm256_mul_pd(r, RegisterConversion.ToV256(math.pow(RegisterConversion.ToDouble4(y), RegisterConversion.ToDouble4(z)))); v256 negative = Avx.mm256_andnot_pd(ABS_MASK, a); v256 floorX = Avx.mm256_floor_pd(a); @@ -499,7 +498,7 @@ public static float gamma(float x) float absX = math.abs(x); float rcp = math.rcp(absX); - math.isnan(double.PositiveInfinity); + if (ix >= 0x7F80_0000) { return x + float.PositiveInfinity; @@ -610,7 +609,7 @@ public static float2 gamma(float2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.gamma_ps(RegisterConversion.ToV128(x), 2)); + return RegisterConversion.ToFloat2(Xse.gamma_ps(RegisterConversion.ToV128(x), 2)); } else { @@ -624,7 +623,7 @@ public static float3 gamma(float3 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.gamma_ps(RegisterConversion.ToV128(x), 3)); + return RegisterConversion.ToFloat3(Xse.gamma_ps(RegisterConversion.ToV128(x), 3)); } else { @@ -638,7 +637,7 @@ public static float4 gamma(float4 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.gamma_ps(RegisterConversion.ToV128(x), 4)); + return RegisterConversion.ToFloat4(Xse.gamma_ps(RegisterConversion.ToV128(x), 4)); } else { @@ -782,7 +781,7 @@ public static double2 gamma(double2 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.gamma_pd(RegisterConversion.ToV128(x))); + return RegisterConversion.ToDouble2(Xse.gamma_pd(RegisterConversion.ToV128(x))); } else { @@ -796,7 +795,7 @@ public static double3 gamma(double3 x) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_gamma_pd(RegisterConversion.ToV256(x), 3)); + return RegisterConversion.ToDouble3(Xse.mm256_gamma_pd(RegisterConversion.ToV256(x), 3)); } else { @@ -810,7 +809,7 @@ public static double4 gamma(double4 x) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_gamma_pd(RegisterConversion.ToV256(x), 4)); + return RegisterConversion.ToDouble4(Xse.mm256_gamma_pd(RegisterConversion.ToV256(x), 4)); } else { diff --git a/Runtime/Math Lib/Functions/Special Functions/Inverse Hyperbolic Functions.cs b/Runtime/Math Lib/Functions/Special Functions/Inverse Hyperbolic Functions.cs index d22430e..b9dc1a3 100644 --- a/Runtime/Math Lib/Functions/Special Functions/Inverse Hyperbolic Functions.cs +++ b/Runtime/Math Lib/Functions/Special Functions/Inverse Hyperbolic Functions.cs @@ -1,7 +1,6 @@ using System.Runtime.CompilerServices; using Unity.Mathematics; using Unity.Burst.Intrinsics; -using MaxMath.Intrinsics; using static Unity.Burst.Intrinsics.X86; @@ -88,7 +87,7 @@ public static float atanh(float x) if (Sse2.IsSse2Supported || Arm.Neon.IsNeonSupported) { float2 xx = x; - xx = addsub(xx, 1f); + xx = addsub(1f, xx); xx = 0.5f * math.log(xx); return (xx - xx.yy).x; @@ -106,7 +105,7 @@ public static float2 atanh(float2 x) if (Sse2.IsSse2Supported || Arm.Neon.IsNeonSupported) { float4 xxyy = x.xxyy; - xxyy = addsub(xxyy, 1f); + xxyy = addsub(1f, xxyy); xxyy = 0.5f * math.log(xxyy); return (xxyy - xxyy.yyww).xz; @@ -204,7 +203,7 @@ public static double atanh(double x) if (Sse2.IsSse2Supported || Arm.Neon.IsNeonSupported) { double2 xx = x; - xx = addsub(xx, 1d); + xx = addsub(1d, xx); xx = 0.5d * math.log(xx); return (xx - xx.yy).x; diff --git a/Runtime/Math Lib/Functions/Special Functions/float8 Unity Mathematics API.cs b/Runtime/Math Lib/Functions/Special Functions/float8 Unity Mathematics API.cs index 77117e1..0a2c71b 100644 --- a/Runtime/Math Lib/Functions/Special Functions/float8 Unity Mathematics API.cs +++ b/Runtime/Math Lib/Functions/Special Functions/float8 Unity Mathematics API.cs @@ -28,7 +28,7 @@ public static float8 round(float8 x) { if (Avx.IsAvxSupported) { - return Avx.mm256_round_ps(x, (int)RoundingMode.FROUND_NINT_NOEXC); + return Avx.mm256_round_ps(x, (int)RoundingMode.FROUND_CUR_DIRECTION); } else { diff --git a/Runtime/Math Lib/Functions/Type Conversion/Int Base 2 Logartihm to Float.cs b/Runtime/Math Lib/Functions/Type Conversion/Int Base 2 Logartihm to Float.cs index ba776e8..472a375 100644 --- a/Runtime/Math Lib/Functions/Type Conversion/Int Base 2 Logartihm to Float.cs +++ b/Runtime/Math Lib/Functions/Type Conversion/Int Base 2 Logartihm to Float.cs @@ -1,9 +1,9 @@ -using System.Runtime.CompilerServices; -using Unity.Mathematics; +using System.Runtime.CompilerServices; using Unity.Burst.Intrinsics; +using Unity.Mathematics; -using static Unity.Burst.Intrinsics.X86; using static MaxMath.LUT.FLOATING_POINT; +using static Unity.Burst.Intrinsics.X86; namespace MaxMath { @@ -16,7 +16,21 @@ public static float exp2(int x, Promise noOverflow = Promise.Nothing) { if (!noOverflow.Promises(Promise.NoOverflow)) { - x = math.clamp(x, nabs(F32_EXPONENT_BIAS), math.abs(F32_EXPONENT_BIAS) + 1); + if (Sse4_1.IsSse41Supported) + { + v128 MIN_EXPONENT = Sse2.cvtsi32_si128(nabs(F32_EXPONENT_BIAS) << F32_MANTISSA_BITS); + v128 MAX_EXPONENT = Sse2.cvtsi32_si128((math.abs(F32_EXPONENT_BIAS) + 1) << F32_MANTISSA_BITS); + v128 BIAS = Sse2.cvtsi32_si128(math.abs(F32_EXPONENT_BIAS) << F32_MANTISSA_BITS); + + v128 mov = Sse2.cvtsi32_si128(x << F32_MANTISSA_BITS); + v128 clamped = Sse4_1.max_epi32(MIN_EXPONENT, Sse4_1.min_epi32(mov, MAX_EXPONENT)); + + return Sse2.add_epi32(BIAS, clamped).Float0; + } + else + { + x = math.clamp(x, nabs(F32_EXPONENT_BIAS), math.abs(F32_EXPONENT_BIAS) + 1); + } } return math.asfloat((math.abs(F32_EXPONENT_BIAS) << F32_MANTISSA_BITS) + (x << F32_MANTISSA_BITS)); @@ -35,7 +49,7 @@ public static float2 exp2(int2 x, Promise noOverflow = Promise.Nothing) return math.asfloat((math.abs(F32_EXPONENT_BIAS) << F32_MANTISSA_BITS) + (x << F32_MANTISSA_BITS)); } - /// Returns the componentwise base-2 exponential of . + /// Returns the componentwise base-2 exponential of . /// A '' with its flag set returns undefined results for any x outside the interval [-127, 128]. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float3 exp2(int3 x, Promise noOverflow = Promise.Nothing) @@ -48,7 +62,7 @@ public static float3 exp2(int3 x, Promise noOverflow = Promise.Nothing) return math.asfloat((math.abs(F32_EXPONENT_BIAS) << F32_MANTISSA_BITS) + (x << F32_MANTISSA_BITS)); } - /// Returns the componentwise base-2 exponential of . + /// Returns the componentwise base-2 exponential of . /// A '' with its flag set returns undefined results for any x outside the interval [-127, 128]. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float4 exp2(int4 x, Promise noOverflow = Promise.Nothing) diff --git a/Runtime/Math Lib/Functions/Bitwise/Type Punning.cs b/Runtime/Math Lib/Functions/Type Conversion/Type Punning.cs similarity index 100% rename from Runtime/Math Lib/Functions/Bitwise/Type Punning.cs rename to Runtime/Math Lib/Functions/Type Conversion/Type Punning.cs diff --git a/Runtime/Math Lib/Functions/Bitwise/Type Punning.cs.meta b/Runtime/Math Lib/Functions/Type Conversion/Type Punning.cs.meta similarity index 100% rename from Runtime/Math Lib/Functions/Bitwise/Type Punning.cs.meta rename to Runtime/Math Lib/Functions/Type Conversion/Type Punning.cs.meta diff --git a/Runtime/Math Lib/Functions/Type Conversion/UNSAFE Boolean Conversion.cs b/Runtime/Math Lib/Functions/Type Conversion/UNSAFE Boolean Conversion.cs index 741438e..8474a10 100644 --- a/Runtime/Math Lib/Functions/Type Conversion/UNSAFE Boolean Conversion.cs +++ b/Runtime/Math Lib/Functions/Type Conversion/UNSAFE Boolean Conversion.cs @@ -1204,7 +1204,7 @@ public static bool3 tobool(short3 x) if (Sse2.IsSse2Supported) { - RegisterConversion.ToType(Sse2.packs_epi16(x, x)); + RegisterConversion.ToBool3(Sse2.packs_epi16(x, x)); } return tobool((byte3)x); @@ -1221,7 +1221,7 @@ public static bool4 tobool(short4 x) if (Sse2.IsSse2Supported) { - RegisterConversion.ToType(Sse2.packs_epi16(x, x)); + RegisterConversion.ToBool4(Sse2.packs_epi16(x, x)); } return tobool((byte4)x); @@ -1309,7 +1309,7 @@ public static bool3 tobool(ushort3 x) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Sse2.packs_epi16(x, x)); + return RegisterConversion.ToBool3(Sse2.packs_epi16(x, x)); } return tobool((byte3)x); @@ -1326,7 +1326,7 @@ public static bool4 tobool(ushort4 x) if (Sse2.IsSse2Supported) { - RegisterConversion.ToType(Sse2.packs_epi16(x, x)); + RegisterConversion.ToBool4(Sse2.packs_epi16(x, x)); } return tobool((byte4)x); @@ -1398,13 +1398,13 @@ public static bool2 tobool(int2 x) { if (Ssse3.IsSsse3Supported) { - return RegisterConversion.ToType(Ssse3.shuffle_epi8(RegisterConversion.ToV128(x), new v128(0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); + return RegisterConversion.ToBool2(Ssse3.shuffle_epi8(RegisterConversion.ToV128(x), new v128(0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); } else if (Sse2.IsSse2Supported) { v128 epi16 = Sse2.packs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(x)); - return RegisterConversion.ToType(Sse2.packus_epi16(epi16, epi16)); + return RegisterConversion.ToBool2(Sse2.packus_epi16(epi16, epi16)); } else { @@ -1418,13 +1418,13 @@ public static bool3 tobool(int3 x) { if (Ssse3.IsSsse3Supported) { - return RegisterConversion.ToType(Ssse3.shuffle_epi8(RegisterConversion.ToV128(x), new v128(0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); + return RegisterConversion.ToBool3(Ssse3.shuffle_epi8(RegisterConversion.ToV128(x), new v128(0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); } else if (Sse2.IsSse2Supported) { v128 epi16 = Sse2.packs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(x)); - return RegisterConversion.ToType(Sse2.packus_epi16(epi16, epi16)); + return RegisterConversion.ToBool3(Sse2.packus_epi16(epi16, epi16)); } else { @@ -1438,13 +1438,13 @@ public static bool4 tobool(int4 x) { if (Ssse3.IsSsse3Supported) { - return RegisterConversion.ToType(Ssse3.shuffle_epi8(RegisterConversion.ToV128(x), new v128(0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); + return RegisterConversion.ToBool4(Ssse3.shuffle_epi8(RegisterConversion.ToV128(x), new v128(0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); } else if (Sse2.IsSse2Supported) { v128 epi16 = Sse2.packs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(x)); - return RegisterConversion.ToType(Sse2.packus_epi16(epi16, epi16)); + return RegisterConversion.ToBool4(Sse2.packus_epi16(epi16, epi16)); } else { @@ -1475,13 +1475,13 @@ public static bool2 tobool(uint2 x) { if (Ssse3.IsSsse3Supported) { - return RegisterConversion.ToType(Ssse3.shuffle_epi8(RegisterConversion.ToV128(x), new v128(0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); + return RegisterConversion.ToBool2(Ssse3.shuffle_epi8(RegisterConversion.ToV128(x), new v128(0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); } else if (Sse2.IsSse2Supported) { v128 epi16 = Sse2.packs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(x)); - return RegisterConversion.ToType(Sse2.packus_epi16(epi16, epi16)); + return RegisterConversion.ToBool2(Sse2.packus_epi16(epi16, epi16)); } else { @@ -1495,13 +1495,13 @@ public static bool3 tobool(uint3 x) { if (Ssse3.IsSsse3Supported) { - return RegisterConversion.ToType(Ssse3.shuffle_epi8(RegisterConversion.ToV128(x), new v128(0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); + return RegisterConversion.ToBool3(Ssse3.shuffle_epi8(RegisterConversion.ToV128(x), new v128(0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); } else if (Sse2.IsSse2Supported) { v128 epi16 = Sse2.packs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(x)); - return RegisterConversion.ToType(Sse2.packus_epi16(epi16, epi16)); + return RegisterConversion.ToBool3(Sse2.packus_epi16(epi16, epi16)); } else { @@ -1516,13 +1516,13 @@ public static bool4 tobool(uint4 x) { if (Ssse3.IsSsse3Supported) { - return RegisterConversion.ToType(Ssse3.shuffle_epi8(RegisterConversion.ToV128(x), new v128(0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); + return RegisterConversion.ToBool4(Ssse3.shuffle_epi8(RegisterConversion.ToV128(x), new v128(0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); } else if (Sse2.IsSse2Supported) { v128 epi16 = Sse2.packs_epi32(RegisterConversion.ToV128(x), RegisterConversion.ToV128(x)); - return RegisterConversion.ToType(Sse2.packus_epi16(epi16, epi16)); + return RegisterConversion.ToBool4(Sse2.packus_epi16(epi16, epi16)); } else { diff --git a/Runtime/Math Lib/Functions/Type Conversion/UNSAFE Double Long Conversions.cs b/Runtime/Math Lib/Functions/Type Conversion/UNSAFE Double Long Conversions.cs index 393b45e..f45efce 100644 --- a/Runtime/Math Lib/Functions/Type Conversion/UNSAFE Double Long Conversions.cs +++ b/Runtime/Math Lib/Functions/Type Conversion/UNSAFE Double Long Conversions.cs @@ -5,7 +5,7 @@ using static Unity.Burst.Intrinsics.X86; using static MaxMath.LUT.CVT_INT_FP; - + namespace MaxMath { namespace Intrinsics @@ -17,7 +17,7 @@ public static v128 usfcvtpd_epu64(v128 a) { if (Sse2.IsSse2Supported) { - v128 MASK = new v128(LIMIT_PRECISE_I32_F64); + v128 MASK = new v128(LIMIT_PRECISE_U64_F64); return Sse2.xor_pd(Sse2.add_pd(a, MASK), MASK); } @@ -29,7 +29,7 @@ public static v128 usfcvttpd_epu64(v128 a) { if (Sse2.IsSse2Supported) { - return usfcvtpd_epu64(RegisterConversion.ToV128(math.trunc(RegisterConversion.ToType(a)))); + return usfcvtpd_epu64(RegisterConversion.ToV128(math.trunc(RegisterConversion.ToDouble2(a)))); } else throw new IllegalInstructionException(); } @@ -39,7 +39,7 @@ public static v256 mm256_usfcvtpd_epu64(v256 a) { if (Avx.IsAvxSupported) { - v256 MASK = new v256(LIMIT_PRECISE_I32_F64); + v256 MASK = new v256(LIMIT_PRECISE_U64_F64); return Avx.mm256_xor_pd(Avx.mm256_add_pd(a, MASK), MASK); } @@ -74,7 +74,7 @@ public static v128 usfcvttpd_epi64(v128 a) { if (Sse2.IsSse2Supported) { - return usfcvtpd_epi64(RegisterConversion.ToV128(math.trunc(RegisterConversion.ToType(a)))); + return usfcvtpd_epi64(RegisterConversion.ToV128(math.trunc(RegisterConversion.ToDouble2(a)))); } else throw new IllegalInstructionException(); } @@ -107,7 +107,7 @@ public static v128 usfcvtepu64_pd(v128 a) { if (Sse2.IsSse2Supported) { - v128 MASK = new v128(LIMIT_PRECISE_I32_F64); + v128 MASK = new v128(LIMIT_PRECISE_U64_F64); return Sse2.sub_pd(Sse2.or_si128(a, MASK), MASK); } @@ -119,7 +119,7 @@ public static v256 mm256_usfcvtepu64_pd(v256 a) { if (Avx.IsAvxSupported) { - v256 MASK = new v256(LIMIT_PRECISE_I32_F64); + v256 MASK = new v256(LIMIT_PRECISE_U64_F64); return Avx.mm256_sub_pd(Avx.mm256_or_pd(a, MASK), MASK); } @@ -315,7 +315,7 @@ public static double2 todoubleunsafe(ulong2 x, Promise promise = Promise.Unsafe0 { if (promise.Promises(Promise.Unsafe0)) { - return RegisterConversion.ToType(Xse.usfcvtepu64_pd(x)); + return RegisterConversion.ToDouble2(Xse.usfcvtepu64_pd(x)); } else { @@ -337,7 +337,7 @@ public static double3 todoubleunsafe(ulong3 x, Promise promise = Promise.Unsafe0 { if (promise.Promises(Promise.Unsafe0)) { - return RegisterConversion.ToType(Xse.mm256_usfcvtepu64_pd(x)); + return RegisterConversion.ToDouble3(Xse.mm256_usfcvtepu64_pd(x)); } else { @@ -359,7 +359,7 @@ public static double4 todoubleunsafe(ulong4 x, Promise promise = Promise.Unsafe0 { if (promise.Promises(Promise.Unsafe0)) { - return RegisterConversion.ToType(Xse.mm256_usfcvtepu64_pd(x)); + return RegisterConversion.ToDouble4(Xse.mm256_usfcvtepu64_pd(x)); } else { @@ -382,7 +382,7 @@ public static double2 todoubleunsafe(long2 x, Promise promise = Promise.Unsafe0) { if (promise.Promises(Promise.Unsafe0)) { - return RegisterConversion.ToType(Xse.usfcvtepi64_pd(x)); + return RegisterConversion.ToDouble2(Xse.usfcvtepi64_pd(x)); } else { @@ -404,7 +404,7 @@ public static double3 todoubleunsafe(long3 x, Promise promise = Promise.Unsafe0) { if (promise.Promises(Promise.Unsafe0)) { - return RegisterConversion.ToType(Xse.mm256_usfcvtepi64_pd(x)); + return RegisterConversion.ToDouble3(Xse.mm256_usfcvtepi64_pd(x)); } else { @@ -426,7 +426,7 @@ public static double4 todoubleunsafe(long4 x, Promise promise = Promise.Unsafe0) { if (promise.Promises(Promise.Unsafe0)) { - return RegisterConversion.ToType(Xse.mm256_usfcvtepi64_pd(x)); + return RegisterConversion.ToDouble4(Xse.mm256_usfcvtepi64_pd(x)); } else { diff --git a/Runtime/Math Lib/Functions/Type Conversion/UNSAFE Quarter Conversion.cs b/Runtime/Math Lib/Functions/Type Conversion/UNSAFE Quarter Conversion.cs index 8550ef5..5cce623 100644 --- a/Runtime/Math Lib/Functions/Type Conversion/UNSAFE Quarter Conversion.cs +++ b/Runtime/Math Lib/Functions/Type Conversion/UNSAFE Quarter Conversion.cs @@ -1,10 +1,8 @@ using System.Runtime.CompilerServices; using Unity.Mathematics; -using Unity.Burst.Intrinsics; -using MaxMath.Intrinsics; using static Unity.Burst.Intrinsics.X86; - + namespace MaxMath { unsafe public static partial class maxmath @@ -691,7 +689,7 @@ public static quarter8 toquarterunsafe(half8 x, Promise promise = Promise.NoOver { if (Sse2.IsSse2Supported) { - return quarter.Vectorized.cvtph_pq(RegisterConversion.ToV128(x), promiseInRange: promise.Promises(Promise.NoOverflow), promiseAbsolute: promise.Promises(Promise.ZeroOrGreater), 8); + return quarter.Vectorized.cvtph_pq(x, promiseInRange: promise.Promises(Promise.NoOverflow), promiseAbsolute: promise.Promises(Promise.ZeroOrGreater), 8); } else { diff --git a/Runtime/Math Lib/Functions/Unity Mathematics Replacements/SIMD (u)int DIV and REM.cs b/Runtime/Math Lib/Functions/Unity Mathematics Replacements/SIMD (u)int DIV and REM.cs index 5b9505a..37c7275 100644 --- a/Runtime/Math Lib/Functions/Unity Mathematics Replacements/SIMD (u)int DIV and REM.cs +++ b/Runtime/Math Lib/Functions/Unity Mathematics Replacements/SIMD (u)int DIV and REM.cs @@ -8,71 +8,71 @@ namespace MaxMath { unsafe public static partial class maxmath { - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint div(byte dividend, byte divisor) => (uint)dividend / (uint)divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte2 div(byte2 dividend, byte2 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte3 div(byte3 dividend, byte3 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte4 div(byte4 dividend, byte4 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte8 div(byte8 dividend, byte8 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte16 div(byte16 dividend, byte16 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte32 div(byte32 dividend, byte32 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint div(ushort dividend, ushort divisor) => (uint)dividend / (uint)divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort2 div(ushort2 dividend, ushort2 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort3 div(ushort3 dividend, ushort3 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort4 div(ushort4 dividend, ushort4 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort8 div(ushort8 dividend, ushort8 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort16 div(ushort16 dividend, ushort16 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint div(uint dividend, uint divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint2 div(uint2 dividend, uint2 divisor) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.div_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 2)); + return RegisterConversion.ToUInt2(Xse.div_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 2)); } else { @@ -80,13 +80,13 @@ public static uint2 div(uint2 dividend, uint2 divisor) } } - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint3 div(uint3 dividend, uint3 divisor) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.div_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 3)); + return RegisterConversion.ToUInt3(Xse.div_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 3)); } else { @@ -94,13 +94,13 @@ public static uint3 div(uint3 dividend, uint3 divisor) } } - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint4 div(uint4 dividend, uint4 divisor) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.div_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 4)); + return RegisterConversion.ToUInt4(Xse.div_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 4)); } else { @@ -108,93 +108,93 @@ public static uint4 div(uint4 dividend, uint4 divisor) } } - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint8 div(uint8 dividend, uint8 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong div(ulong dividend, ulong divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong2 div(ulong2 dividend, ulong2 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong3 div(ulong3 dividend, ulong3 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong4 div(ulong4 dividend, ulong4 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int div(sbyte dividend, sbyte divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte2 div(sbyte2 dividend, sbyte2 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte3 div(sbyte3 dividend, sbyte3 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte4 div(sbyte4 dividend, sbyte4 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte8 div(sbyte8 dividend, sbyte8 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte16 div(sbyte16 dividend, sbyte16 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte32 div(sbyte32 dividend, sbyte32 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int div(short dividend, short divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short2 div(short2 dividend, short2 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short3 div(short3 dividend, short3 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short4 div(short4 dividend, short4 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short8 div(short8 dividend, short8 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short16 div(short16 dividend, short16 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int div(int dividend, int divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int2 div(int2 dividend, int2 divisor) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.div_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 2)); + return RegisterConversion.ToInt2(Xse.div_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 2)); } else { @@ -202,13 +202,13 @@ public static int2 div(int2 dividend, int2 divisor) } } - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int3 div(int3 dividend, int3 divisor) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.div_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 3)); + return RegisterConversion.ToInt3(Xse.div_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 3)); } else { @@ -216,13 +216,13 @@ public static int3 div(int3 dividend, int3 divisor) } } - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int4 div(int4 dividend, int4 divisor) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.div_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 4)); + return RegisterConversion.ToInt4(Xse.div_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 4)); } else { @@ -230,89 +230,89 @@ public static int4 div(int4 dividend, int4 divisor) } } - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int8 div(int8 dividend, int8 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long div(long dividend, long divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long2 div(long2 dividend, long2 divisor) => dividend / divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long3 div(long3 dividend, long3 divisor) => dividend / divisor; - /// Divides by and returns the result. <%summary> + /// Divides '' by '' and returns the result. <%summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint mod(byte dividend, byte divisor) => (uint)dividend % (uint)divisor; - /// Divides by and returns the result. <%summary> + /// Divides '' by '' and returns the result. <%summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte2 mod(byte2 dividend, byte2 divisor) => dividend % divisor; - /// Divides by and returns the result. <%summary> + /// Divides '' by '' and returns the result. <%summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte3 mod(byte3 dividend, byte3 divisor) => dividend % divisor; - /// Divides by and returns the result. <%summary> + /// Divides '' by '' and returns the result. <%summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte4 mod(byte4 dividend, byte4 divisor) => dividend % divisor; - /// Divides by and returns the result. <%summary> + /// Divides '' by '' and returns the result. <%summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte8 mod(byte8 dividend, byte8 divisor) => dividend % divisor; - /// Divides by and returns the result. <%summary> + /// Divides '' by '' and returns the result. <%summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte16 mod(byte16 dividend, byte16 divisor) => dividend % divisor; - /// Divides by and returns the result. <%summary> + /// Divides '' by '' and returns the result. <%summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte32 mod(byte32 dividend, byte32 divisor) => dividend % divisor; - /// Divides by and returns the result. <%summary> + /// Divides '' by '' and returns the result. <%summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint mod(ushort dividend, ushort divisor) => (uint)dividend % (uint)divisor; - /// Divides by and returns the result. <%summary> + /// Divides '' by '' and returns the result. <%summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort2 mod(ushort2 dividend, ushort2 divisor) => dividend % divisor; - /// Divides by and returns the result. <%summary> + /// Divides '' by '' and returns the result. <%summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort3 mod(ushort3 dividend, ushort3 divisor) => dividend % divisor; - /// Divides by and returns the result. <%summary> + /// Divides '' by '' and returns the result. <%summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort4 mod(ushort4 dividend, ushort4 divisor) => dividend % divisor; - /// Divides by and returns the result. <%summary> + /// Divides '' by '' and returns the result. <%summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort8 mod(ushort8 dividend, ushort8 divisor) => dividend % divisor; - /// Divides by and returns the result. <%summary> + /// Divides '' by '' and returns the result. <%summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort16 mod(ushort16 dividend, ushort16 divisor) => dividend % divisor; - /// Divides by and returns the result. <%summary> + /// Divides '' by '' and returns the result. <%summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint mod(uint dividend, uint divisor) => dividend % divisor; - /// Divides by and returns the modainder. + /// Divides '' by '' and returns the remainder. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint2 mod(uint2 dividend, uint2 divisor) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.rem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 2)); + return RegisterConversion.ToUInt2(Xse.rem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 2)); } else { @@ -320,13 +320,13 @@ public static uint2 mod(uint2 dividend, uint2 divisor) } } - /// Divides by and returns the modainder. + /// Divides '' by '' and returns the remainder. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint3 mod(uint3 dividend, uint3 divisor) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.rem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 3)); + return RegisterConversion.ToUInt3(Xse.rem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 3)); } else { @@ -334,13 +334,13 @@ public static uint3 mod(uint3 dividend, uint3 divisor) } } - /// Divides by and returns the modainder. + /// Divides '' by '' and returns the remainder. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint4 mod(uint4 dividend, uint4 divisor) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.rem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 4)); + return RegisterConversion.ToUInt4(Xse.rem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 4)); } else { @@ -348,89 +348,89 @@ public static uint4 mod(uint4 dividend, uint4 divisor) } } - /// Divides by and returns the result. <%summary> + /// Divides '' by '' and returns the result. <%summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint8 mod(uint8 dividend, uint8 divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong mod(ulong dividend, ulong divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong2 mod(ulong2 dividend, ulong2 divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong3 mod(ulong3 dividend, ulong3 divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong4 mod(ulong4 dividend, ulong4 divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int mod(sbyte dividend, sbyte divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte2 mod(sbyte2 dividend, sbyte2 divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte3 mod(sbyte3 dividend, sbyte3 divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte4 mod(sbyte4 dividend, sbyte4 divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte8 mod(sbyte8 dividend, sbyte8 divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte16 mod(sbyte16 dividend, sbyte16 divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte32 mod(sbyte32 dividend, sbyte32 divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int mod(short dividend, short divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short2 mod(short2 dividend, short2 divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short3 mod(short3 dividend, short3 divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short4 mod(short4 dividend, short4 divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short8 mod(short8 dividend, short8 divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short16 mod(short16 dividend, short16 divisor) => dividend % divisor; - /// Divides by and returns the modainder. + /// Divides '' by '' and returns the remainder. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int2 mod(int2 dividend, int2 divisor) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.rem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 2)); + return RegisterConversion.ToInt2(Xse.rem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 2)); } else { @@ -438,13 +438,13 @@ public static int2 mod(int2 dividend, int2 divisor) } } - /// Divides by and returns the modainder. + /// Divides '' by '' and returns the remainder. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int3 mod(int3 dividend, int3 divisor) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.rem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 3)); + return RegisterConversion.ToInt3(Xse.rem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 3)); } else { @@ -452,13 +452,13 @@ public static int3 mod(int3 dividend, int3 divisor) } } - /// Divides by and returns the modainder. + /// Divides '' by '' and returns the remainder. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int4 mod(int4 dividend, int4 divisor) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.rem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 4)); + return RegisterConversion.ToInt4(Xse.rem_epu32(RegisterConversion.ToV128(dividend), RegisterConversion.ToV128(divisor), 4)); } else { @@ -466,20 +466,20 @@ public static int4 mod(int4 dividend, int4 divisor) } } - /// Divides by and returns the result. <%summary> + /// Divides '' by '' and returns the result. <%summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int8 mod(int8 dividend, int8 divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long mod(long dividend, long divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long2 mod(long2 dividend, long2 divisor) => dividend % divisor; - /// Divides by and returns the result. + /// Divides '' by '' and returns the result. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long3 mod(long3 dividend, long3 divisor) => dividend % divisor; } diff --git a/Runtime/Math Lib/Types/Enum/Promise.cs b/Runtime/Math Lib/Types/Enum/Promise.cs index 7a40183..4c6f696 100644 --- a/Runtime/Math Lib/Types/Enum/Promise.cs +++ b/Runtime/Math Lib/Types/Enum/Promise.cs @@ -1,10 +1,12 @@ using System; using System.Runtime.CompilerServices; +using Unity.Burst.CompilerServices; namespace MaxMath { unsafe public static partial class maxmath { + /// An optional parameter for functions that selects optimized code paths. Must be or it will add significant overhead instead. [Flags] public enum Promise : byte { @@ -31,29 +33,43 @@ internal static class PromiseExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool Promises(this maxmath.Promise p, maxmath.Promise flags) { +#if DEBUG +if (Constant.IsConstantExpression(1) && !(Constant.IsConstantExpression(p))) +{ + throw new ArgumentException("A maxmath.Promise used as an argument must be constant, since it adds significant overhead instead of chosing an optimized code path otherwise."); +} +#endif return (p & flags) == flags; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static byte CountUnsafeLevels(this maxmath.Promise p) { +#if DEBUG +if (Constant.IsConstantExpression(1) && !(Constant.IsConstantExpression(p))) +{ + throw new ArgumentException("A maxmath.Promise used as an argument must be constant, since it adds significant overhead instead of chosing an optimized code path otherwise."); +} +#endif if (p.Promises(maxmath.Promise.Unsafe3)) return 4; if (p.Promises(maxmath.Promise.Unsafe2)) return 3; if (p.Promises(maxmath.Promise.Unsafe1)) return 2; if (p.Promises(maxmath.Promise.Unsafe0)) return 1; - - else return 0; + return 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static maxmath.Promise GetDemotedUnsafeLevels(this maxmath.Promise p) { +#if DEBUG +if (Constant.IsConstantExpression(1) && !(Constant.IsConstantExpression(p))) +{ + throw new ArgumentException("A maxmath.Promise used as an argument must be constant, since it adds significant overhead instead of chosing an optimized code path otherwise."); +} +#endif const maxmath.Promise USF_MASK = maxmath.Promise.Unsafe1 | maxmath.Promise.Unsafe2 | maxmath.Promise.Unsafe3; - p &= USF_MASK; - p = (maxmath.Promise)((byte)p >> 1); - - return p; + return (maxmath.Promise)(byte)((uint)((byte)p & (byte)USF_MASK) >> 1); } } } diff --git a/Runtime/Math Lib/Types/Random/Random16.cs b/Runtime/Math Lib/Types/Random/Random16.cs index b277dfa..5049f83 100644 --- a/Runtime/Math Lib/Types/Random/Random16.cs +++ b/Runtime/Math Lib/Types/Random/Random16.cs @@ -69,9 +69,9 @@ private ushort NextState() ushort temp = State; - State = (ushort)(State ^ State << 7); - State = (ushort)(State ^ State >> 9); - State = (ushort)(State ^ State << 13); + State = (ushort)(State ^ (ushort)(State << 7)); + State = (ushort)(State ^ (ushort)(State >> 9)); + State = (ushort)(State ^ (ushort)(State << 13)); return temp; } diff --git a/Runtime/Math Lib/Types/Random/Random32.cs b/Runtime/Math Lib/Types/Random/Random32.cs index f366a79..c29c80b 100644 --- a/Runtime/Math Lib/Types/Random/Random32.cs +++ b/Runtime/Math Lib/Types/Random/Random32.cs @@ -6,7 +6,6 @@ using MaxMath.Intrinsics; using static Unity.Burst.Intrinsics.X86; -using static MaxMath.maxmath; namespace MaxMath { @@ -217,7 +216,7 @@ public int2 NextInt2(int2 min, int2 max) v128 hiProd = Sse2.mul_epu32(Sse2.unpacklo_epi64(Sse2.cvtsi32_si128((int)NextState()), Sse2.cvtsi32_si128((int)NextState())), (ulong2)(max - min)); hiProd = Sse2.shuffle_epi32(hiProd, Sse.SHUFFLE(0, 0, 3, 1)); - return min + RegisterConversion.ToType(hiProd); + return min + RegisterConversion.ToInt2(hiProd); } else { @@ -243,7 +242,7 @@ public int3 NextInt3(int3 min, int3 max) hi = Sse2.mul_epu32(hi, Sse2.bsrli_si128(RegisterConversion.ToV128(dif), 2 * sizeof(int))); v128 result = Sse.shuffle_ps(lo, hi, Sse.SHUFFLE(3, 1, 3, 1)); - return min + RegisterConversion.ToType(result); + return min + RegisterConversion.ToInt3(result); } else { @@ -270,7 +269,7 @@ public int4 NextInt4(int4 min, int4 max) hi = Sse2.mul_epu32(hi, (ulong2)(uint2)(dif.zw)); v128 result = Sse.shuffle_ps(lo, hi, Sse.SHUFFLE(3, 1, 3, 1)); - return min + RegisterConversion.ToType(result); + return min + RegisterConversion.ToInt4(result); } else { @@ -365,7 +364,7 @@ public uint2 NextUInt2(uint2 max) v128 hiProd = Sse2.mul_epu32(Sse2.unpacklo_epi64(Sse2.cvtsi32_si128((int)NextState()), Sse2.cvtsi32_si128((int)NextState())), (ulong2)max); hiProd = Sse2.shuffle_epi32(hiProd, Sse.SHUFFLE(0, 0, 3, 1)); - return RegisterConversion.ToType(hiProd); + return RegisterConversion.ToUInt2(hiProd); } else { @@ -385,7 +384,7 @@ public uint3 NextUInt3(uint3 max) hi = Sse2.mul_epu32(hi, Sse2.bsrli_si128(RegisterConversion.ToV128(max), 2 * sizeof(int))); v128 result = Sse.shuffle_ps(lo, hi, Sse.SHUFFLE(3, 1, 3, 1)); - return RegisterConversion.ToType(result); + return RegisterConversion.ToUInt3(result); } else { @@ -405,7 +404,7 @@ public uint4 NextUInt4(uint4 max) hi = Sse2.mul_epu32(hi, (ulong2)(max.zw)); v128 result = Sse.shuffle_ps(lo, hi, Sse.SHUFFLE(3, 1, 3, 1)); - return RegisterConversion.ToType(result); + return RegisterConversion.ToUInt4(result); } else { @@ -453,7 +452,7 @@ public uint2 NextUInt2(uint2 min, uint2 max) v128 hiProd = Sse2.mul_epu32(Sse2.unpacklo_epi64(Sse2.cvtsi32_si128((int)NextState()), Sse2.cvtsi32_si128((int)NextState())), (ulong2)(max - min)); hiProd = Sse2.shuffle_epi32(hiProd, Sse.SHUFFLE(0, 0, 3, 1)); - return min + RegisterConversion.ToType(hiProd); + return min + RegisterConversion.ToUInt2(hiProd); } else { @@ -475,7 +474,7 @@ public uint3 NextUInt3(uint3 min, uint3 max) hi = Sse2.mul_epu32(hi, Sse2.bsrli_si128(RegisterConversion.ToV128(dif), 2 * sizeof(int))); v128 result = Sse.shuffle_ps(lo, hi, Sse.SHUFFLE(3, 1, 3, 1)); - return min + RegisterConversion.ToType(result); + return min + RegisterConversion.ToUInt3(result); } else { @@ -497,7 +496,7 @@ public uint4 NextUInt4(uint4 min, uint4 max) hi = Sse2.mul_epu32(hi, (ulong2)(dif.zw)); v128 result = Sse.shuffle_ps(lo, hi, Sse.SHUFFLE(3, 1, 3, 1)); - return min + RegisterConversion.ToType(result); + return min + RegisterConversion.ToUInt4(result); } else { diff --git a/Runtime/Math Lib/Types/Random/Random8.cs b/Runtime/Math Lib/Types/Random/Random8.cs index b0e721b..7265c4a 100644 --- a/Runtime/Math Lib/Types/Random/Random8.cs +++ b/Runtime/Math Lib/Types/Random/Random8.cs @@ -1,6 +1,5 @@ using System; using System.Runtime.CompilerServices; -using Unity.Burst.Intrinsics; using Unity.Mathematics; using DevTools; using MaxMath.Intrinsics; @@ -70,9 +69,9 @@ private byte NextState() byte temp = State; - State = (byte)(State ^ (State << 7)); - State = (byte)(State ^ (State >> 5)); - State = (byte)(State ^ (State << 3)); + State = (byte)(State ^ (byte)(State << 7)); + State = (byte)(State ^ (byte)(State >> 5)); + State = (byte)(State ^ (byte)(State << 3)); return temp; } diff --git a/Runtime/Math Lib/Types/Scalar/Int128.cs b/Runtime/Math Lib/Types/Scalar/Int128.cs index 7a96439..7368b08 100644 --- a/Runtime/Math Lib/Types/Scalar/Int128.cs +++ b/Runtime/Math Lib/Types/Scalar/Int128.cs @@ -15,7 +15,8 @@ namespace MaxMath { - [Serializable] [DebuggerTypeProxy(typeof(Int128.DebuggerProxy))] + [Serializable] + [DebuggerTypeProxy(typeof(Int128.DebuggerProxy))] unsafe public struct Int128 : IComparable, IComparable, IConvertible, IEquatable, IEquatable, IEquatable, IFormattable { internal sealed class DebuggerProxy @@ -1611,13 +1612,50 @@ public override int GetHashCode() #region string - public override string ToString() + internal const byte MAX_DECIMAL_DIGITS = 39; + + public override string ToString() { - return ((BigInteger)this).ToString(); + if (IsZero) + { + return "0"; + } + + char* DECIMAL_DIGITS = stackalloc char[10] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + + char* result = stackalloc char[MAX_DECIMAL_DIGITS + 1]; + char* currentDigit = result + (MAX_DECIMAL_DIGITS + 1 - 1); + UInt128 cpy = (UInt128)abs(this); + + while (cpy >= 10u) + { + cpy = UInt128.__const.divrem10(cpy, out ulong rem); + + *currentDigit-- = DECIMAL_DIGITS[rem]; + } + if (cpy.IsNotZero) + { + *currentDigit-- = DECIMAL_DIGITS[cpy.lo64]; + } + if ((long)hi64 < 0) + { + *currentDigit-- = '-'; + } + + int length = (MAX_DECIMAL_DIGITS + 1) - (int)(((ulong)++currentDigit - (ulong)result) / sizeof(char)); + + return new string(currentDigit, 0, length); } - - public string ToString(string format) + + public string ToString(string format) { + if (format == "X" || format == "x") + { + string hex = DevTools.Dump.Hex(this, false); + + return (format == "x") ? hex.ToLower() : hex; + } + return ((BigInteger)this).ToString(format); } diff --git a/Runtime/Math Lib/Types/Scalar/UInt128.cs b/Runtime/Math Lib/Types/Scalar/UInt128.cs index e689578..aad0ed9 100644 --- a/Runtime/Math Lib/Types/Scalar/UInt128.cs +++ b/Runtime/Math Lib/Types/Scalar/UInt128.cs @@ -15,7 +15,8 @@ namespace MaxMath { - [Serializable] [DebuggerTypeProxy(typeof(UInt128.DebuggerProxy))] + [Serializable] + [DebuggerTypeProxy(typeof(UInt128.DebuggerProxy))] unsafe public partial struct UInt128 : IComparable, IComparable, IConvertible, IEquatable, IEquatable, IEquatable, IFormattable { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator == (UInt128 left, sbyte right) @@ -1767,13 +1768,46 @@ public override int GetHashCode() #region string + internal const byte MAX_DECIMAL_DIGITS = 39; + public override string ToString() { - return ((BigInteger)this).ToString(); + if (IsZero) + { + return "0"; + } + + char* DECIMAL_DIGITS = stackalloc char[10] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + + char* result = stackalloc char[MAX_DECIMAL_DIGITS]; + char* currentDigit = result + (MAX_DECIMAL_DIGITS - 1); + UInt128 cpy = this; + + while (cpy >= 10u) + { + cpy = __const.divrem10(cpy, out ulong rem); + + *currentDigit-- = DECIMAL_DIGITS[rem]; + } + if (cpy.IsNotZero) + { + *currentDigit-- = DECIMAL_DIGITS[cpy.lo64]; + } + + int length = MAX_DECIMAL_DIGITS - (int)(((ulong)++currentDigit - (ulong)result) / sizeof(char)); + + return new string(currentDigit, 0, length); } public string ToString(string format) { + if (format == "X" || format == "x") + { + string hex = DevTools.Dump.Hex(this, false); + + return (format == "x") ? hex.ToLower() : hex; + } + return ((BigInteger)this).ToString(format); } diff --git a/Runtime/Math Lib/Types/Scalar/quarter.cs b/Runtime/Math Lib/Types/Scalar/quarter.cs index 5785121..af176d5 100644 --- a/Runtime/Math Lib/Types/Scalar/quarter.cs +++ b/Runtime/Math Lib/Types/Scalar/quarter.cs @@ -837,11 +837,11 @@ public static implicit operator double4(quarter q) return IsNotZero(left); } - bool nan = isnan(left) | isnan(right); - bool zero = !IsZero(left) | !IsZero(right); - bool value = left.value != right.value; + bool bothZero = IsZero(new quarter((byte)(left.value | right.value))); + bool value = left.value != right.value; + bool nan = isnan(left) | isnan(right); - return nan | (zero & value); + return nan | !bothZero | value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -938,7 +938,34 @@ public static implicit operator double4(quarter q) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator < (quarter left, quarter right) { - return (float)left < (float)right; + if (Xse.constexpr.IS_TRUE(right.value == 0) || Xse.constexpr.IS_TRUE(right.value == 0b1000_0000)) + { + bool negative = left.value > 0b0111_1111; + bool notZero = (left.value & 0b0111_1111) != 0; + + return !isnan(left) & (notZero & negative); + } + if (Xse.constexpr.IS_TRUE(left.value == 0) || Xse.constexpr.IS_TRUE(left.value == 0b1000_0000)) + { + bool positive = right.value < 0b1000_0000; + bool notZero = (right.value & 0b0111_1111) != 0; + + return !isnan(right) & (positive & notZero); + } + + + int signA = left.value >> 7; + int signB = right.value >> 7; + + bool notNaN = !isnan(left) & !isnan(right); + bool equalSigns = signA == signB; + bool differentValues = left.value != right.value; + bool notBothZero = (byte)((left.value | right.value) << 1) != 0; + + bool ifEqualSigns = differentValues & (tobool(signA) ^ (right.value > left.value)); + bool ifOppositeSigns = notBothZero & tobool(signA); + + return notNaN & (equalSigns ? ifEqualSigns : ifOppositeSigns); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -979,52 +1006,57 @@ public static implicit operator double4(quarter q) [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator > (quarter left, quarter right) - { - return (float)left > (float)right; - } + public static bool operator > (quarter left, quarter right) => right < left; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator > (half left, quarter right) - { - return (float)left > (float)right; - } + public static bool operator > (half left, quarter right) => right < left; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator > (quarter left, half right) - { - return (float)left > (float)right; - } + public static bool operator > (quarter left, half right) => right < left; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator > (float left, quarter right) - { - return left > (float)right; - } + public static bool operator > (float left, quarter right) => right < left; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator > (quarter left, float right) - { - return (float)left > right; - } + public static bool operator > (quarter left, float right) => right < left; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator > (double left, quarter right) - { - return left > (double)right; - } + public static bool operator > (double left, quarter right) => right < left; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator > (quarter left, double right) - { - return (double)left > right; - } + public static bool operator > (quarter left, double right) => right < left; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator <= (quarter left, quarter right) { - return (float)left <= (float)right; + if (Xse.constexpr.IS_TRUE(right.value == 0) || Xse.constexpr.IS_TRUE(right.value == 0b1000_0000)) + { + bool intLEzero = 1 > (sbyte)left.value; + + return !isnan(left) & intLEzero; + } + if (Xse.constexpr.IS_TRUE(left.value == 0) || Xse.constexpr.IS_TRUE(left.value == 0b1000_0000)) + { + bool uintGEzero = (sbyte)right.value > 0; + bool negativeZero = right.value == 0b1000_0000; + + return !isnan(right) & (uintGEzero | negativeZero); + } + + + int signA = left.value >> 7; + int signB = right.value >> 7; + + bool notNaN = !isnan(left) & !isnan(right); + bool equalSigns = signA == signB; + bool equalValues = left.value == right.value; + bool bothZero = (byte)((left.value | right.value) << 1) == 0; + + bool ifEqualSigns = equalValues | (tobool(signA) ^ (right.value > left.value)); + bool ifOppositeSigns = bothZero | tobool(signA); + + return notNaN & (equalSigns ? ifEqualSigns : ifOppositeSigns); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1065,46 +1097,25 @@ public static implicit operator double4(quarter q) [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator >= (quarter left, quarter right) - { - return (float)left >= (float)right; - } + public static bool operator >= (quarter left, quarter right) => right <= left; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator >= (half left, quarter right) - { - return (float)left >= (float)right; - } + public static bool operator >= (half left, quarter right) => right <= left; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator >= (quarter left, half right) - { - return (float)left >= (float)right; - } + public static bool operator >= (quarter left, half right) => right <= left; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator >= (float left, quarter right) - { - return left >= (float)right; - } + public static bool operator >= (float left, quarter right) => right <= left; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator >= (quarter left, float right) - { - return (float)left >= right; - } + public static bool operator >= (quarter left, float right) => right <= left; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator >= (double left, quarter right) - { - return left >= (double)right; - } + public static bool operator >= (double left, quarter right) => right <= left; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator >= (quarter left, double right) - { - return (double)left >= right; - } + public static bool operator >= (quarter left, double right) => right <= left; [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Runtime/Math Lib/Types/Vectors/bool/bool16.cs b/Runtime/Math Lib/Types/Vectors/bool/bool16.cs index 05c6d9b..8837418 100644 --- a/Runtime/Math Lib/Types/Vectors/bool/bool16.cs +++ b/Runtime/Math Lib/Types/Vectors/bool/bool16.cs @@ -3,6 +3,7 @@ using System.Runtime.InteropServices; using Unity.Mathematics; using Unity.Burst.Intrinsics; +using MaxMath.Intrinsics; using DevTools; using static Unity.Burst.Intrinsics.X86; @@ -13,8 +14,6 @@ namespace MaxMath [StructLayout(LayoutKind.Explicit, Size = 16 * sizeof(bool))] unsafe public struct bool16 : IEquatable { - [FieldOffset(0)] private fixed bool asArray[16]; - [FieldOffset(0)] [MarshalAs(UnmanagedType.U1)] public bool x0; [FieldOffset(1)] [MarshalAs(UnmanagedType.U1)] public bool x1; [FieldOffset(2)] [MarshalAs(UnmanagedType.U1)] public bool x2; @@ -168,11 +167,11 @@ public bool16(bool8 x01234567, bool8 x8_9_10_11_12_13_14_15) public bool2 v2_14 { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get => maxmath.tobool(maxmath.tobyte(this).v2_14); [MethodImpl(MethodImplOptions.AggressiveInlining)] set { byte16 temp = maxmath.tobyte(this); temp.v2_14 = maxmath.tobyte(value); this = maxmath.tobool(temp); } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] // Burst optimizes this; (worse) alternatives: Sse4_1.stream_load_si128(void* ptr) Sse.load_ps(void* ptr) - public static implicit operator v128(bool16 input) => new v128(*(byte*)&input.x0, *(byte*)&input.x1, *(byte*)&input.x2, *(byte*)&input.x3, *(byte*)&input.x4, *(byte*)&input.x5, *(byte*)&input.x6, *(byte*)&input.x7, *(byte*)&input.x8, *(byte*)&input.x9, *(byte*)&input.x10, *(byte*)&input.x11, *(byte*)&input.x12, *(byte*)&input.x13, *(byte*)&input.x14, *(byte*)&input.x15); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator v128(bool16 input) => new v128 { Byte0 = *(byte*)&input.x0, Byte1 = *(byte*)&input.x1, Byte2 = *(byte*)&input.x2, Byte3 = *(byte*)&input.x3, Byte4 = *(byte*)&input.x4, Byte5 = *(byte*)&input.x5, Byte6 = *(byte*)&input.x6, Byte7 = *(byte*)&input.x7, Byte8 = *(byte*)&input.x8, Byte9 = *(byte*)&input.x9, Byte10 = *(byte*)&input.x10, Byte11 = *(byte*)&input.x11, Byte12 = *(byte*)&input.x12, Byte13 = *(byte*)&input.x13, Byte14 = *(byte*)&input.x14, Byte15 = *(byte*)&input.x15 }; - [MethodImpl(MethodImplOptions.AggressiveInlining)] // Burst optimizes this; (worse) alternatives: Sse.store_ps(void* ptr, v128 x) - public static implicit operator bool16(v128 input) => new bool16 { x0 = maxmath.tobool(input.Byte0), x1 = maxmath.tobool(input.Byte1), x2 = maxmath.tobool(input.Byte2), x3 = maxmath.tobool(input.Byte3), x4 = maxmath.tobool(input.Byte4), x5 = maxmath.tobool(input.Byte5), x6 = maxmath.tobool(input.Byte6), x7 = maxmath.tobool(input.Byte7), x8 = maxmath.tobool(input.Byte8), x9 = maxmath.tobool(input.Byte9), x10 = maxmath.tobool(input.Byte10), x11 = maxmath.tobool(input.Byte11), x12 = maxmath.tobool(input.Byte12), x13 = maxmath.tobool(input.Byte13), x14 = maxmath.tobool(input.Byte14), x15 = maxmath.tobool(input.Byte15)}; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator bool16(v128 input) => new bool16 { x0 = maxmath.tobool(input.Byte0), x1 = maxmath.tobool(input.Byte1), x2 = maxmath.tobool(input.Byte2), x3 = maxmath.tobool(input.Byte3), x4 = maxmath.tobool(input.Byte4), x5 = maxmath.tobool(input.Byte5), x6 = maxmath.tobool(input.Byte6), x7 = maxmath.tobool(input.Byte7), x8 = maxmath.tobool(input.Byte8), x9 = maxmath.tobool(input.Byte9), x10 = maxmath.tobool(input.Byte10), x11 = maxmath.tobool(input.Byte11), x12 = maxmath.tobool(input.Byte12), x13 = maxmath.tobool(input.Byte13), x14 = maxmath.tobool(input.Byte14), x15 = maxmath.tobool(input.Byte15) }; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator bool16(bool x) => new bool16(x); @@ -216,15 +215,34 @@ readonly get { Assert.IsWithinArrayBounds(index, 16); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return maxmath.tobool(Xse.extract_epi8(this, (byte)index)); + } + else + { + bool16 onStack = this; + + return *((bool*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { Assert.IsWithinArrayBounds(index, 16); - - asArray[index] = value; + + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi8(this, *(byte*)&value, (byte)index); + } + else + { + bool16 onStack = this; + *((bool*)&onStack + index) = value; + + this = onStack; + } } } diff --git a/Runtime/Math Lib/Types/Vectors/bool/bool32.cs b/Runtime/Math Lib/Types/Vectors/bool/bool32.cs index 14a1aca..87b84d5 100644 --- a/Runtime/Math Lib/Types/Vectors/bool/bool32.cs +++ b/Runtime/Math Lib/Types/Vectors/bool/bool32.cs @@ -3,9 +3,11 @@ using System.Runtime.InteropServices; using Unity.Mathematics; using Unity.Burst.Intrinsics; +using MaxMath.Intrinsics; using DevTools; using static Unity.Burst.Intrinsics.X86; +using Unity.Burst.CompilerServices; namespace MaxMath { @@ -13,8 +15,6 @@ namespace MaxMath [StructLayout(LayoutKind.Explicit, Size = 32 * sizeof(bool))] unsafe public struct bool32 : IEquatable { - [FieldOffset(0)] private fixed bool asArray[32]; - [FieldOffset(0)] internal bool16 _v16_0; [FieldOffset(16)] internal bool16 _v16_16; @@ -240,13 +240,14 @@ public bool32(bool16 v16_0, bool16 v16_1) public bool2 v2_30 { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => maxmath.tobool(maxmath.tobyte(this).v2_30); [MethodImpl(MethodImplOptions.AggressiveInlining)] set { byte32 temp = maxmath.tobyte(this); temp.v2_30 = maxmath.tobyte(value); this = maxmath.tobool(temp); } } #endregion + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator v256(bool32 input) => new v256 { Byte0 = maxmath.tobyte(input.x0), Byte1 = maxmath.tobyte(input.x1), Byte2 = maxmath.tobyte(input.x2), Byte3 = maxmath.tobyte(input.x3), Byte4 = maxmath.tobyte(input.x4), Byte5 = maxmath.tobyte(input.x5), Byte6 = maxmath.tobyte(input.x6), Byte7 = maxmath.tobyte(input.x7), Byte8 = maxmath.tobyte(input.x8), Byte9 = maxmath.tobyte(input.x9), Byte10 = maxmath.tobyte(input.x10), Byte11 = maxmath.tobyte(input.x11), Byte12 = maxmath.tobyte(input.x12), Byte13 = maxmath.tobyte(input.x13), Byte14 = maxmath.tobyte(input.x14), Byte15 = maxmath.tobyte(input.x15), Byte16 = maxmath.tobyte(input.x16), Byte17 = maxmath.tobyte(input.x17), Byte18 = maxmath.tobyte(input.x18), Byte19 = maxmath.tobyte(input.x19), Byte20 = maxmath.tobyte(input.x20), Byte21 = maxmath.tobyte(input.x21), Byte22 = maxmath.tobyte(input.x22), Byte23 = maxmath.tobyte(input.x23), Byte24 = maxmath.tobyte(input.x24), Byte25 = maxmath.tobyte(input.x25), Byte26 = maxmath.tobyte(input.x26), Byte27 = maxmath.tobyte(input.x27), Byte28 = maxmath.tobyte(input.x28), Byte29 = maxmath.tobyte(input.x29), Byte30 = maxmath.tobyte(input.x30), Byte31 = maxmath.tobyte(input.x31) }; - [MethodImpl(MethodImplOptions.AggressiveInlining)] // Burst optimizes this; (worse) alternatives: Sse4_1.stream_load_si128(void* ptr) Sse.load_ps(void* ptr) - public static implicit operator v256(bool32 input) => new v256(*(byte*)&input.x0, *(byte*)&input.x1, *(byte*)&input.x2, *(byte*)&input.x3, *(byte*)&input.x4, *(byte*)&input.x5, *(byte*)&input.x6, *(byte*)&input.x7, *(byte*)&input.x8, *(byte*)&input.x9, *(byte*)&input.x10, *(byte*)&input.x11, *(byte*)&input.x12, *(byte*)&input.x13, *(byte*)&input.x14, *(byte*)&input.x15, *(byte*)&input.x16, *(byte*)&input.x17, *(byte*)&input.x18, *(byte*)&input.x19, *(byte*)&input.x20, *(byte*)&input.x21, *(byte*)&input.x22, *(byte*)&input.x23, *(byte*)&input.x24, *(byte*)&input.x25, *(byte*)&input.x26, *(byte*)&input.x27, *(byte*)&input.x28, *(byte*)&input.x29, *(byte*)&input.x30, *(byte*)&input.x31); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] // Burst optimizes this; (worse) alternatives: Sse.store_ps(void* ptr, v256 x) + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator bool32(v256 input) => new bool32 { x0 = maxmath.tobool(input.Byte0), x1 = maxmath.tobool(input.Byte1), x2 = maxmath.tobool(input.Byte2), x3 = maxmath.tobool(input.Byte3), x4 = maxmath.tobool(input.Byte4), x5 = maxmath.tobool(input.Byte5), x6 = maxmath.tobool(input.Byte6), x7 = maxmath.tobool(input.Byte7), x8 = maxmath.tobool(input.Byte8), x9 = maxmath.tobool(input.Byte9), x10 = maxmath.tobool(input.Byte10), x11 = maxmath.tobool(input.Byte11), x12 = maxmath.tobool(input.Byte12), x13 = maxmath.tobool(input.Byte13), x14 = maxmath.tobool(input.Byte14), x15 = maxmath.tobool(input.Byte15), x16 = maxmath.tobool(input.Byte16), x17 = maxmath.tobool(input.Byte17), x18 = maxmath.tobool(input.Byte18), x19 = maxmath.tobool(input.Byte19), x20 = maxmath.tobool(input.Byte20), x21 = maxmath.tobool(input.Byte21), x22 = maxmath.tobool(input.Byte22), x23 = maxmath.tobool(input.Byte23), x24 = maxmath.tobool(input.Byte24), x25 = maxmath.tobool(input.Byte25), x26 = maxmath.tobool(input.Byte26), x27 = maxmath.tobool(input.Byte27), x28 = maxmath.tobool(input.Byte28), x29 = maxmath.tobool(input.Byte29), x30 = maxmath.tobool(input.Byte30), x31 = maxmath.tobool(input.Byte31) }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator bool32(bool x) => new bool32(x); @@ -273,7 +274,7 @@ public bool32(bool16 v16_0, bool16 v16_1) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_andnot_si256(val, new byte32(1)); + return Avx2.mm256_andnot_si256(val, Avx.mm256_set1_epi8(1)); } else { @@ -289,7 +290,28 @@ readonly get { Assert.IsWithinArrayBounds(index, 32); - return asArray[index]; + if (Avx2.IsAvx2Supported) + { + return maxmath.tobool(Xse.mm256_extract_epi8(this, (byte)index)); + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 16) + { + return maxmath.tobool(Xse.extract_epi8(_v16_0, (byte)index)); + } + else + { + return maxmath.tobool(Xse.extract_epi8(_v16_16, (byte)(index - 16))); + } + } + } + + bool32 onStack = this; + + return *((bool*)&onStack + index); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -297,7 +319,33 @@ readonly get { Assert.IsWithinArrayBounds(index, 32); - asArray[index] = value; + if (Avx2.IsAvx2Supported) + { + this = Xse.mm256_insert_epi8(this, *(byte*)&value, (byte)index); + + return; + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 16) + { + _v16_0 = Xse.insert_epi8(_v16_0, *(byte*)&value, (byte)index); + } + else + { + _v16_16 = Xse.insert_epi8(_v16_16, *(byte*)&value, (byte)(index - 16)); + } + + return; + } + } + + bool32 onStack = this; + *((bool*)&onStack + index) = value; + + this = onStack; } } diff --git a/Runtime/Math Lib/Types/Vectors/bool/bool8.cs b/Runtime/Math Lib/Types/Vectors/bool/bool8.cs index e18777d..46b2a91 100644 --- a/Runtime/Math Lib/Types/Vectors/bool/bool8.cs +++ b/Runtime/Math Lib/Types/Vectors/bool/bool8.cs @@ -3,6 +3,7 @@ using System.Runtime.InteropServices; using Unity.Mathematics; using Unity.Burst.Intrinsics; +using MaxMath.Intrinsics; using DevTools; using static Unity.Burst.Intrinsics.X86; @@ -13,9 +14,6 @@ namespace MaxMath [StructLayout(LayoutKind.Explicit, Size = 8 * sizeof(bool))] unsafe public struct bool8 : IEquatable { - [FieldOffset(0)] private fixed bool asArray[8]; - [FieldOffset(0)] private fixed ulong alias_long[1]; // somehow this unused line of code DE-confuses the compiler when writing back to memory - [FieldOffset(0)] [MarshalAs(UnmanagedType.U1)] public bool x0; [FieldOffset(1)] [MarshalAs(UnmanagedType.U1)] public bool x1; [FieldOffset(2)] [MarshalAs(UnmanagedType.U1)] public bool x2; @@ -110,25 +108,46 @@ public bool8(bool4 x0123, bool4 x4567) [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(bool8 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(bool8 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.Byte0 = *(byte*)&input.x0; + result.Byte1 = *(byte*)&input.x1; + result.Byte2 = *(byte*)&input.x2; + result.Byte3 = *(byte*)&input.x3; + result.Byte4 = *(byte*)&input.x4; + result.Byte5 = *(byte*)&input.x5; + result.Byte6 = *(byte*)&input.x6; + result.Byte7 = *(byte*)&input.x7; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator bool8(v128 input) { -#if DEBUG - return new bool8 { x0 = maxmath.tobool(input.Byte0), - x1 = maxmath.tobool(input.Byte1), - x2 = maxmath.tobool(input.Byte2), - x3 = maxmath.tobool(input.Byte3), - x4 = maxmath.tobool(input.Byte4), - x5 = maxmath.tobool(input.Byte5), - x6 = maxmath.tobool(input.Byte6), - x7 = maxmath.tobool(input.Byte7) }; -#else - long x = input.SLong0; - - return *(bool8*)&x; -#endif + bool8 result; + + result.x0 = maxmath.tobool(input.Byte0); + result.x1 = maxmath.tobool(input.Byte1); + result.x2 = maxmath.tobool(input.Byte2); + result.x3 = maxmath.tobool(input.Byte3); + result.x4 = maxmath.tobool(input.Byte4); + result.x5 = maxmath.tobool(input.Byte5); + result.x6 = maxmath.tobool(input.Byte6); + result.x7 = maxmath.tobool(input.Byte7); + + return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -173,7 +192,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 8); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return maxmath.tobool(Xse.extract_epi8(this, (byte)index)); + } + else + { + bool8 onStack = this; + + return *((bool*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -181,7 +209,17 @@ readonly get { Assert.IsWithinArrayBounds(index, 8); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi8(this, *(byte*)&value, (byte)index); + } + else + { + bool8 onStack = this; + *((bool*)&onStack + index) = value; + + this = onStack; + } } } diff --git a/Runtime/Math Lib/Types/Vectors/byte/byte16.cs b/Runtime/Math Lib/Types/Vectors/byte/byte16.cs index 49141ae..937b600 100644 --- a/Runtime/Math Lib/Types/Vectors/byte/byte16.cs +++ b/Runtime/Math Lib/Types/Vectors/byte/byte16.cs @@ -58,8 +58,6 @@ public DebuggerProxy(byte16 v) } - [FieldOffset(0)] private fixed byte asArray[16]; - [FieldOffset(0)] public byte x0; [FieldOffset(1)] public byte x1; [FieldOffset(2)] public byte x2; @@ -1562,7 +1560,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 0); + this = Xse.insert_epi16(this, *(ushort*)&value, 0); } else { @@ -1620,7 +1618,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 1); + this = Xse.insert_epi16(this, *(ushort*)&value, 1); } else { @@ -1678,7 +1676,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 2); + this = Xse.insert_epi16(this, *(ushort*)&value, 2); } else { @@ -1736,7 +1734,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 3); + this = Xse.insert_epi16(this, *(ushort*)&value, 3); } else { @@ -1794,7 +1792,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 4); + this = Xse.insert_epi16(this, *(ushort*)&value, 4); } else { @@ -1852,7 +1850,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 5); + this = Xse.insert_epi16(this, *(ushort*)&value, 5); } else { @@ -1910,7 +1908,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 6); + this = Xse.insert_epi16(this, *(ushort*)&value, 6); } else { @@ -1968,7 +1966,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 7); + this = Xse.insert_epi16(this, *(ushort*)&value, 7); } else { @@ -1979,12 +1977,13 @@ readonly get } #endregion - + [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(byte16 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(byte16 input) => new v128{ Byte0 = input.x0, Byte1 = input.x1, Byte2 = input.x2, Byte3 = input.x3, Byte4 = input.x4, Byte5 = input.x5, Byte6 = input.x6, Byte7 = input.x7, Byte8 = input.x8, Byte9 = input.x9, Byte10 = input.x10, Byte11 = input.x11, Byte12 = input.x12, Byte13 = input.x13, Byte14 = input.x14, Byte15 = input.x15 }; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator byte16(v128 input) => RegisterConversion.ToType(input); + public static implicit operator byte16(v128 input) => new byte16{ x0 = input.Byte0, x1 = input.Byte1, x2 = input.Byte2, x3 = input.Byte3, x4 = input.Byte4, x5 = input.Byte5, x6 = input.Byte6, x7 = input.Byte7, x8 = input.Byte8, x9 = input.Byte9, x10 = input.Byte10, x11 = input.Byte11, x12 = input.Byte12, x13 = input.Byte13, x14 = input.Byte14, x15 = input.Byte15 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator byte16(byte input) => new byte16(input); @@ -2072,7 +2071,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 16); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return Xse.extract_epi8(this, (byte)index); + } + else + { + byte16 onStack = this; + + return *((byte*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -2080,7 +2088,17 @@ readonly get { Assert.IsWithinArrayBounds(index, 16); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi8(this, value, (byte)index); + } + else + { + byte16 onStack = this; + *((byte*)&onStack + index) = value; + + this = onStack; + } } } @@ -2332,7 +2350,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); + return RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); } else { @@ -2345,7 +2363,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmplt_epu8(left, right, 16)); + return RegisterConversion.IsTrue8(Xse.cmplt_epu8(left, right, 16)); } else { @@ -2358,7 +2376,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmpgt_epu8(left, right, 16)); + return RegisterConversion.IsTrue8(Xse.cmpgt_epu8(left, right, 16)); } else { @@ -2372,7 +2390,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); + return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); } else { @@ -2385,7 +2403,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmple_epu8(left, right, 16)); + return RegisterConversion.IsTrue8(Xse.cmple_epu8(left, right, 16)); } else { @@ -2398,7 +2416,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmpge_epu8(left, right, 16)); + return RegisterConversion.IsTrue8(Xse.cmpge_epu8(left, right, 16)); } else { diff --git a/Runtime/Math Lib/Types/Vectors/byte/byte2.cs b/Runtime/Math Lib/Types/Vectors/byte/byte2.cs index 97b4342..f6adaaa 100644 --- a/Runtime/Math Lib/Types/Vectors/byte/byte2.cs +++ b/Runtime/Math Lib/Types/Vectors/byte/byte2.cs @@ -31,8 +31,6 @@ public DebuggerProxy(byte2 v) } - [FieldOffset(0)] private fixed byte asArray[2]; - [FieldOffset(0)] public byte x; [FieldOffset(1)] public byte y; @@ -538,10 +536,28 @@ public readonly byte2 yy [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(byte2 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(byte2 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.Byte0 = input.x; + result.Byte1 = input.y; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator byte2(v128 input) => RegisterConversion.ToType(input); + public static implicit operator byte2(v128 input) => new byte2 { x = input.Byte0, y = input.Byte1 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator byte2(byte input) => new byte2(input); @@ -679,7 +695,7 @@ public static implicit operator int2(byte2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu8_epi32(input)); + return RegisterConversion.ToInt2(Xse.cvtepu8_epi32(input)); } else { @@ -692,7 +708,7 @@ public static implicit operator uint2(byte2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu8_epi32(input)); + return RegisterConversion.ToUInt2(Xse.cvtepu8_epi32(input)); } else { @@ -734,7 +750,7 @@ public static implicit operator float2(byte2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu8_ps(input)); + return RegisterConversion.ToFloat2(Xse.cvtepu8_ps(input)); } else { @@ -753,7 +769,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 2); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return Xse.extract_epi8(this, (byte)index); + } + else + { + byte2 onStack = this; + + return *((byte*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -761,7 +786,17 @@ readonly get { Assert.IsWithinArrayBounds(index, 2); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi8(this, value, (byte)index); + } + else + { + byte2 onStack = this; + *((byte*)&onStack + index) = value; + + this = onStack; + } } } @@ -990,7 +1025,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); + v128 result = RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); + + return *(bool2*)&result; } else { @@ -1003,7 +1040,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmplt_epu8(left, right, 2)); + v128 result = RegisterConversion.IsTrue8(Xse.cmplt_epu8(left, right, 2)); + + return *(bool2*)&result; } else { @@ -1016,7 +1055,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmpgt_epu8(left, right, 2)); + v128 result = RegisterConversion.IsTrue8(Xse.cmpgt_epu8(left, right, 2)); + + return *(bool2*)&result; } else { @@ -1030,7 +1071,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); + v128 result = RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); + + return *(bool2*)&result; } else { @@ -1043,7 +1086,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmple_epu8(left, right, 8)); + v128 result = RegisterConversion.IsTrue8(Xse.cmple_epu8(left, right, 8)); + + return *(bool2*)&result; } else { @@ -1056,7 +1101,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmpge_epu8(left, right, 8)); + v128 result = RegisterConversion.IsTrue8(Xse.cmpge_epu8(left, right, 8)); + + return *(bool2*)&result; } else { diff --git a/Runtime/Math Lib/Types/Vectors/byte/byte3.cs b/Runtime/Math Lib/Types/Vectors/byte/byte3.cs index b2e0c07..9a19ae4 100644 --- a/Runtime/Math Lib/Types/Vectors/byte/byte3.cs +++ b/Runtime/Math Lib/Types/Vectors/byte/byte3.cs @@ -33,8 +33,6 @@ public DebuggerProxy(byte3 v) } - [FieldOffset(0)] private fixed byte asArray[3]; - [FieldOffset(0)] public byte x; [FieldOffset(1)] public byte y; [FieldOffset(2)] public byte z; @@ -2060,13 +2058,32 @@ public readonly byte2 zz } } #endregion - + [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(byte3 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(byte3 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.Byte0 = input.x; + result.Byte1 = input.y; + result.Byte2 = input.z; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator byte3(v128 input) => RegisterConversion.ToType(input); + public static implicit operator byte3(v128 input) => new byte3 { x = input.Byte0, y = input.Byte1, z = input.Byte2 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator byte3(byte input) => new byte3(input); @@ -2212,7 +2229,7 @@ public static implicit operator int3(byte3 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu8_epi32(input)); + return RegisterConversion.ToInt3(Xse.cvtepu8_epi32(input)); } else { @@ -2225,7 +2242,7 @@ public static implicit operator uint3(byte3 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu8_epi32(input)); + return RegisterConversion.ToUInt3(Xse.cvtepu8_epi32(input)); } else { @@ -2275,7 +2292,7 @@ public static implicit operator float3(byte3 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu8_ps(input)); + return RegisterConversion.ToFloat3(Xse.cvtepu8_ps(input)); } else { @@ -2294,7 +2311,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 3); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return Xse.extract_epi8(this, (byte)index); + } + else + { + byte3 onStack = this; + + return *((byte*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -2302,7 +2328,17 @@ readonly get { Assert.IsWithinArrayBounds(index, 3); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi8(this, value, (byte)index); + } + else + { + byte3 onStack = this; + *((byte*)&onStack + index) = value; + + this = onStack; + } } } @@ -2531,7 +2567,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); + v128 result = RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); + + return *(bool3*)&result; } else { @@ -2544,7 +2582,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmplt_epu8(left, right, 3)); + v128 result = RegisterConversion.IsTrue8(Xse.cmplt_epu8(left, right, 3)); + + return *(bool3*)&result; } else { @@ -2557,7 +2597,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmpgt_epu8(left, right, 3)); + v128 result = RegisterConversion.IsTrue8(Xse.cmpgt_epu8(left, right, 3)); + + return *(bool3*)&result; } else { @@ -2571,7 +2613,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); + v128 result = RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); + + return *(bool3*)&result; } else { @@ -2584,7 +2628,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmple_epu8(left, right, 3)); + v128 result = RegisterConversion.IsTrue8(Xse.cmple_epu8(left, right, 3)); + + return *(bool3*)&result; } else { @@ -2597,7 +2643,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmpge_epu8(left, right, 3)); + v128 result = RegisterConversion.IsTrue8(Xse.cmpge_epu8(left, right, 3)); + + return *(bool3*)&result; } else { diff --git a/Runtime/Math Lib/Types/Vectors/byte/byte32.cs b/Runtime/Math Lib/Types/Vectors/byte/byte32.cs index 5d0f014..d5b9b95 100644 --- a/Runtime/Math Lib/Types/Vectors/byte/byte32.cs +++ b/Runtime/Math Lib/Types/Vectors/byte/byte32.cs @@ -90,8 +90,6 @@ public DebuggerProxy(byte32 v) } - [FieldOffset(0)] private fixed byte asArray[32]; - [FieldOffset(0)] internal byte16 _v16_0; [FieldOffset(16)] internal byte16 _v16_16; @@ -3629,7 +3627,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 0); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 0); } else { @@ -3674,7 +3672,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 1); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 1); } else { @@ -3719,7 +3717,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 2); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 2); } else { @@ -3764,7 +3762,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 3); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 3); } else { @@ -3809,7 +3807,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 4); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 4); } else { @@ -3854,7 +3852,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 5); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 5); } else { @@ -3899,7 +3897,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 6); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 6); } else { @@ -3944,7 +3942,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 7); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 7); } else { @@ -4017,7 +4015,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 8); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 8); } else { @@ -4071,7 +4069,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 9); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 9); } else { @@ -4125,11 +4123,11 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 10); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 10); } else if (Sse2.IsSse2Supported) { - this._v16_16 = Sse2.insert_epi16(this._v16_16, *(short*)&value, 2); + this._v16_16 = Xse.insert_epi16(this._v16_16, *(ushort*)&value, 2); } else { @@ -4184,11 +4182,11 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 11); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 11); } else if (Sse2.IsSse2Supported) { - this._v16_16 = Sse2.insert_epi16(this._v16_16, *(short*)&value, 3); + this._v16_16 = Xse.insert_epi16(this._v16_16, *(ushort*)&value, 3); } else { @@ -4241,7 +4239,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 12); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 12); } else { @@ -4295,7 +4293,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 13); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 13); } else { @@ -4349,7 +4347,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 14); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 14); } else { @@ -4403,7 +4401,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 15); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 15); } else { @@ -4415,10 +4413,11 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v256(byte32 input) => RegisterConversion.ToV256(input); + public static implicit operator v256(byte32 input) => new v256 { Byte0 = input.x0, Byte1 = input.x1, Byte2 = input.x2, Byte3 = input.x3, Byte4 = input.x4, Byte5 = input.x5, Byte6 = input.x6, Byte7 = input.x7, Byte8 = input.x8, Byte9 = input.x9, Byte10 = input.x10, Byte11 = input.x11, Byte12 = input.x12, Byte13 = input.x13, Byte14 = input.x14, Byte15 = input.x15, Byte16 = input.x16, Byte17 = input.x17, Byte18 = input.x18, Byte19 = input.x19, Byte20 = input.x20, Byte21 = input.x21, Byte22 = input.x22, Byte23 = input.x23, Byte24 = input.x24, Byte25 = input.x25, Byte26 = input.x26, Byte27 = input.x27, Byte28 = input.x28, Byte29 = input.x29, Byte30 = input.x30, Byte31 = input.x31 }; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator byte32(v256 input) => RegisterConversion.ToType(input); + public static implicit operator byte32(v256 input) => new byte32 { x0 = input.Byte0, x1 = input.Byte1, x2 = input.Byte2, x3 = input.Byte3, x4 = input.Byte4, x5 = input.Byte5, x6 = input.Byte6, x7 = input.Byte7, x8 = input.Byte8, x9 = input.Byte9, x10 = input.Byte10, x11 = input.Byte11, x12 = input.Byte12, x13 = input.Byte13, x14 = input.Byte14, x15 = input.Byte15, x16 = input.Byte16, x17 = input.Byte17, x18 = input.Byte18, x19 = input.Byte19, x20 = input.Byte20, x21 = input.Byte21, x22 = input.Byte22, x23 = input.Byte23, x24 = input.Byte24, x25 = input.Byte25, x26 = input.Byte26, x27 = input.Byte27, x28 = input.Byte28, x29 = input.Byte29, x30 = input.Byte30, x31 = input.Byte31 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator byte32(byte input) => new byte32(input); @@ -4449,7 +4448,28 @@ readonly get { Assert.IsWithinArrayBounds(index, 32); - return asArray[index]; + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_extract_epi8(this, (byte)index); + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 16) + { + return Xse.extract_epi8(_v16_0, (byte)index); + } + else + { + return Xse.extract_epi8(_v16_16, (byte)(index - 16)); + } + } + } + + byte32 onStack = this; + + return *((byte*)&onStack + index); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -4457,7 +4477,32 @@ readonly get { Assert.IsWithinArrayBounds(index, 32); - asArray[index] = value; + if (Avx2.IsAvx2Supported) + { + this = Xse.mm256_insert_epi8(this, value, (byte)index); + + return; + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 16) + { + _v16_0 = Xse.insert_epi8(_v16_0, value, (byte)index); + } + else + { + _v16_16 = Xse.insert_epi8(_v16_16, value, (byte)(index - 16)); + } + + return; + } + } + + byte32 onStack = this; + *((byte*)&onStack + index) = value; + this = onStack; } } diff --git a/Runtime/Math Lib/Types/Vectors/byte/byte4.cs b/Runtime/Math Lib/Types/Vectors/byte/byte4.cs index d337833..fb64d06 100644 --- a/Runtime/Math Lib/Types/Vectors/byte/byte4.cs +++ b/Runtime/Math Lib/Types/Vectors/byte/byte4.cs @@ -9,7 +9,6 @@ using DevTools; using static Unity.Burst.Intrinsics.X86; -using static MaxMath.maxmath; namespace MaxMath { @@ -35,8 +34,6 @@ public DebuggerProxy(byte4 v) } - [FieldOffset(0)] private fixed byte asArray[4]; - [FieldOffset(0)] public byte x; [FieldOffset(1)] public byte y; [FieldOffset(2)] public byte z; @@ -5892,10 +5889,30 @@ public readonly byte2 ww #endregion [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(byte4 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(byte4 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.Byte0 = input.x; + result.Byte1 = input.y; + result.Byte2 = input.z; + result.Byte3 = input.w; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator byte4(v128 input) => RegisterConversion.ToType(input); + public static implicit operator byte4(v128 input) => new byte4 { x = input.Byte0, y = input.Byte1, z = input.Byte2, w = input.Byte3 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator byte4(byte input) => new byte4(input); @@ -6041,7 +6058,7 @@ public static implicit operator int4(byte4 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu8_epi32(input)); + return RegisterConversion.ToInt4(Xse.cvtepu8_epi32(input)); } else { @@ -6054,7 +6071,7 @@ public static implicit operator uint4(byte4 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu8_epi32(input)); + return RegisterConversion.ToUInt4(Xse.cvtepu8_epi32(input)); } else { @@ -6125,7 +6142,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 4); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return Xse.extract_epi8(this, (byte)index); + } + else + { + byte4 onStack = this; + + return *((byte*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -6133,7 +6159,17 @@ readonly get { Assert.IsWithinArrayBounds(index, 4); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi8(this, value, (byte)index); + } + else + { + byte4 onStack = this; + *((byte*)&onStack + index) = value; + + this = onStack; + } } } @@ -6362,7 +6398,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); + v128 results = RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); + + return *(bool4*)&results; } else { @@ -6375,7 +6413,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmplt_epu8(left, right, 4)); + v128 results = RegisterConversion.IsTrue8(Xse.cmplt_epu8(left, right, 4)); + + return *(bool4*)&results; } else { @@ -6388,7 +6428,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmpgt_epu8(left, right, 4)); + v128 results = RegisterConversion.IsTrue8(Xse.cmpgt_epu8(left, right, 4)); + + return *(bool4*)&results; } else { @@ -6402,7 +6444,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); + v128 results = RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); + + return *(bool4*)&results; } else { @@ -6415,7 +6459,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmple_epu8(left, right, 4)); + v128 results = RegisterConversion.IsTrue8(Xse.cmple_epu8(left, right, 4)); + + return *(bool4*)&results; } else { @@ -6428,7 +6474,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmpge_epu8(left, right, 4)); + v128 results = RegisterConversion.IsTrue8(Xse.cmpge_epu8(left, right, 4)); + + return *(bool4*)&results; } else { diff --git a/Runtime/Math Lib/Types/Vectors/byte/byte8.cs b/Runtime/Math Lib/Types/Vectors/byte/byte8.cs index 26c8d3a..75f04c3 100644 --- a/Runtime/Math Lib/Types/Vectors/byte/byte8.cs +++ b/Runtime/Math Lib/Types/Vectors/byte/byte8.cs @@ -9,7 +9,6 @@ using DevTools; using static Unity.Burst.Intrinsics.X86; -using static MaxMath.maxmath; namespace MaxMath { @@ -43,9 +42,6 @@ public DebuggerProxy(byte8 v) } - [FieldOffset(0)] private fixed byte asArray[8]; - [FieldOffset(0)] private fixed ulong alias_long[1]; // somehow this unused line of code DE-confuses the compiler when writing back to memory - [FieldOffset(0)] public byte x0; [FieldOffset(1)] public byte x1; [FieldOffset(2)] public byte x2; @@ -705,7 +701,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 1); + this = Xse.insert_epi16(this, *(ushort*)&value, 1); } else { @@ -763,7 +759,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 2); + this = Xse.insert_epi16(this, *(ushort*)&value, 2); } else { @@ -821,7 +817,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 3); + this = Xse.insert_epi16(this, *(ushort*)&value, 3); } else { @@ -834,10 +830,48 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(byte8 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(byte8 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.Byte0 = input.x0; + result.Byte1 = input.x1; + result.Byte2 = input.x2; + result.Byte3 = input.x3; + result.Byte4 = input.x4; + result.Byte5 = input.x5; + result.Byte6 = input.x6; + result.Byte7 = input.x7; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator byte8(v128 input) => RegisterConversion.ToType(input); + public static implicit operator byte8(v128 input) + { + byte8 result; + + result.x0 = input.Byte0; + result.x1 = input.Byte1; + result.x2 = input.Byte2; + result.x3 = input.Byte3; + result.x4 = input.Byte4; + result.x5 = input.Byte5; + result.x6 = input.Byte6; + result.x7 = input.Byte7; + + return result; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator byte8(byte input) => new byte8(input); @@ -1004,7 +1038,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 8); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return Xse.extract_epi8(this, (byte)index); + } + else + { + byte8 onStack = this; + + return *((byte*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1012,7 +1055,17 @@ readonly get { Assert.IsWithinArrayBounds(index, 8); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi8(this, value, (byte)index); + } + else + { + byte8 onStack = this; + *((byte*)&onStack + index) = value; + + this = onStack; + } } } @@ -1241,7 +1294,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); + return RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); } else { @@ -1254,7 +1307,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmplt_epu8(left, right, 8)); + return RegisterConversion.IsTrue8(Xse.cmplt_epu8(left, right, 8)); } else { @@ -1267,7 +1320,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmpgt_epu8(left, right, 8)); + return RegisterConversion.IsTrue8(Xse.cmpgt_epu8(left, right, 8)); } else { @@ -1281,7 +1334,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); + return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); } else { @@ -1294,7 +1347,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmple_epu8(left, right, 8)); + return RegisterConversion.IsTrue8(Xse.cmple_epu8(left, right, 8)); } else { @@ -1307,7 +1360,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmpge_epu8(left, right, 8)); + return RegisterConversion.IsTrue8(Xse.cmpge_epu8(left, right, 8)); } else { diff --git a/Runtime/Math Lib/Types/Vectors/byte/sbyte16.cs b/Runtime/Math Lib/Types/Vectors/byte/sbyte16.cs index 1991039..04681ce 100644 --- a/Runtime/Math Lib/Types/Vectors/byte/sbyte16.cs +++ b/Runtime/Math Lib/Types/Vectors/byte/sbyte16.cs @@ -57,8 +57,6 @@ public DebuggerProxy(sbyte16 v) } - [FieldOffset(0)] private fixed sbyte asArray[16]; - [FieldOffset(0)] public sbyte x0; [FieldOffset(1)] public sbyte x1; [FieldOffset(2)] public sbyte x2; @@ -1561,7 +1559,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 0); + this = Xse.insert_epi16(this, *(ushort*)&value, 0); } else { @@ -1619,7 +1617,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 1); + this = Xse.insert_epi16(this, *(ushort*)&value, 1); } else { @@ -1677,7 +1675,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 2); + this = Xse.insert_epi16(this, *(ushort*)&value, 2); } else { @@ -1735,7 +1733,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 3); + this = Xse.insert_epi16(this, *(ushort*)&value, 3); } else { @@ -1793,7 +1791,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 4); + this = Xse.insert_epi16(this, *(ushort*)&value, 4); } else { @@ -1851,7 +1849,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 5); + this = Xse.insert_epi16(this, *(ushort*)&value, 5); } else { @@ -1909,7 +1907,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 6); + this = Xse.insert_epi16(this, *(ushort*)&value, 6); } else { @@ -1967,7 +1965,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 7); + this = Xse.insert_epi16(this, *(ushort*)&value, 7); } else { @@ -1980,10 +1978,11 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(sbyte16 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(sbyte16 input) => new v128{ SByte0 = input.x0, SByte1 = input.x1, SByte2 = input.x2, SByte3 = input.x3, SByte4 = input.x4, SByte5 = input.x5, SByte6 = input.x6, SByte7 = input.x7, SByte8 = input.x8, SByte9 = input.x9, SByte10 = input.x10, SByte11 = input.x11, SByte12 = input.x12, SByte13 = input.x13, SByte14 = input.x14, SByte15 = input.x15 }; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator sbyte16(v128 input) => RegisterConversion.ToType(input); + public static implicit operator sbyte16(v128 input) => new sbyte16{ x0 = input.SByte0, x1 = input.SByte1, x2 = input.SByte2, x3 = input.SByte3, x4 = input.SByte4, x5 = input.SByte5, x6 = input.SByte6, x7 = input.SByte7, x8 = input.SByte8, x9 = input.SByte9, x10 = input.SByte10, x11 = input.SByte11, x12 = input.SByte12, x13 = input.SByte13, x14 = input.SByte14, x15 = input.SByte15 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator sbyte16(sbyte input) => new sbyte16(input); @@ -2071,7 +2070,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 16); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return (sbyte)Xse.extract_epi8(this, (byte)index); + } + else + { + sbyte16 onStack = this; + + return *((sbyte*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -2079,7 +2087,17 @@ readonly get { Assert.IsWithinArrayBounds(index, 16); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi8(this, (byte)value, (byte)index); + } + else + { + sbyte16 onStack = this; + *((sbyte*)&onStack + index) = value; + + this = onStack; + } } } @@ -2353,7 +2371,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); + return RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); } else { @@ -2366,7 +2384,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmplt_epi8(left, right)); + return RegisterConversion.IsTrue8(Xse.cmplt_epi8(left, right)); } else { @@ -2379,7 +2397,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Sse2.cmpgt_epi8(left, right)); + return RegisterConversion.IsTrue8(Sse2.cmpgt_epi8(left, right)); } else { @@ -2393,7 +2411,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); + return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); } else { @@ -2406,7 +2424,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Sse2.cmpgt_epi8(left, right)); + return RegisterConversion.IsFalse8(Sse2.cmpgt_epi8(left, right)); } else { @@ -2419,7 +2437,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Xse.cmplt_epi8(left, right)); + return RegisterConversion.IsFalse8(Xse.cmplt_epi8(left, right)); } else { diff --git a/Runtime/Math Lib/Types/Vectors/byte/sbyte2.cs b/Runtime/Math Lib/Types/Vectors/byte/sbyte2.cs index d286527..9e9f7bf 100644 --- a/Runtime/Math Lib/Types/Vectors/byte/sbyte2.cs +++ b/Runtime/Math Lib/Types/Vectors/byte/sbyte2.cs @@ -31,8 +31,6 @@ public DebuggerProxy(sbyte2 v) } - [FieldOffset(0)] private fixed sbyte asArray[2]; - [FieldOffset(0)] public sbyte x; [FieldOffset(1)] public sbyte y; @@ -538,10 +536,28 @@ public readonly sbyte2 yy [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(sbyte2 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(sbyte2 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.SByte0 = input.x; + result.SByte1 = input.y; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator sbyte2(v128 input) => RegisterConversion.ToType(input); + public static implicit operator sbyte2(v128 input) => new sbyte2 { x = input.SByte0, y = input.SByte1 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator sbyte2(sbyte input) => new sbyte2(input); @@ -679,7 +695,7 @@ public static implicit operator int2(sbyte2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi8_epi32(input)); + return RegisterConversion.ToInt2(Xse.cvtepi8_epi32(input)); } else { @@ -692,7 +708,7 @@ public static explicit operator uint2(sbyte2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi8_epi32(input)); + return RegisterConversion.ToUInt2(Xse.cvtepi8_epi32(input)); } else { @@ -734,7 +750,7 @@ public static implicit operator float2(sbyte2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi8_ps(input)); + return RegisterConversion.ToFloat2(Xse.cvtepi8_ps(input)); } else { @@ -747,7 +763,7 @@ public static implicit operator double2(sbyte2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi8_pd(input)); + return RegisterConversion.ToDouble2(Xse.cvtepi8_pd(input)); } else { @@ -763,7 +779,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 2); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return (sbyte)Xse.extract_epi8(this, (byte)index); + } + else + { + sbyte2 onStack = this; + + return *((sbyte*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -771,7 +796,17 @@ readonly get { Assert.IsWithinArrayBounds(index, 2); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi8(this, (byte)value, (byte)index); + } + else + { + sbyte2 onStack = this; + *((sbyte*)&onStack + index) = value; + + this = onStack; + } } } @@ -1000,12 +1035,7 @@ readonly get { if (Sse2.IsSse2Supported) { - if (Constant.IsConstantExpression(n) && n == 7) - { - return Sse2.cmpgt_epi8(Sse2.setzero_si128(), x); - } - - return (sbyte2)((short2)x >> n); + return Xse.srai_epi8(x, n, 2); } else { @@ -1019,7 +1049,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); + v128 results = RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); + + return *(bool2*)&results; } else { @@ -1032,7 +1064,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmplt_epi8(left, right)); + v128 results = RegisterConversion.IsTrue8(Xse.cmplt_epi8(left, right)); + + return *(bool2*)&results; } else { @@ -1045,7 +1079,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Sse2.cmpgt_epi8(left, right)); + v128 results = RegisterConversion.IsTrue8(Sse2.cmpgt_epi8(left, right)); + + return *(bool2*)&results; } else { @@ -1059,7 +1095,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); + v128 results = RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); + + return *(bool2*)&results; } else { @@ -1072,7 +1110,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Sse2.cmpgt_epi8(left, right)); + v128 results = RegisterConversion.IsFalse8(Sse2.cmpgt_epi8(left, right)); + + return *(bool2*)&results; } else { @@ -1085,7 +1125,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Xse.cmplt_epi8(left, right)); + v128 results = RegisterConversion.IsFalse8(Xse.cmplt_epi8(left, right)); + + return *(bool2*)&results; } else { diff --git a/Runtime/Math Lib/Types/Vectors/byte/sbyte3.cs b/Runtime/Math Lib/Types/Vectors/byte/sbyte3.cs index 4672d2e..4801666 100644 --- a/Runtime/Math Lib/Types/Vectors/byte/sbyte3.cs +++ b/Runtime/Math Lib/Types/Vectors/byte/sbyte3.cs @@ -33,8 +33,6 @@ public DebuggerProxy(sbyte3 v) } - [FieldOffset(0)] private fixed sbyte asArray[3]; - [FieldOffset(0)] public sbyte x; [FieldOffset(1)] public sbyte y; [FieldOffset(2)] public sbyte z; @@ -2063,10 +2061,29 @@ public readonly sbyte2 zz [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(sbyte3 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(sbyte3 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.SByte0 = input.x; + result.SByte1 = input.y; + result.SByte2 = input.z; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator sbyte3(v128 input) => RegisterConversion.ToType(input); + public static implicit operator sbyte3(v128 input) => new sbyte3 { x = input.SByte0, y = input.SByte1, z = input.SByte2 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator sbyte3(sbyte input) => new sbyte3(input); @@ -2212,7 +2229,7 @@ public static implicit operator int3(sbyte3 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi8_epi32(input)); + return RegisterConversion.ToInt3(Xse.cvtepi8_epi32(input)); } else { @@ -2225,7 +2242,7 @@ public static explicit operator uint3(sbyte3 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi8_epi32(input)); + return RegisterConversion.ToUInt3(Xse.cvtepi8_epi32(input)); } else { @@ -2275,7 +2292,7 @@ public static implicit operator float3(sbyte3 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi8_ps(input)); + return RegisterConversion.ToFloat3(Xse.cvtepi8_ps(input)); } else { @@ -2294,7 +2311,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 3); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return (sbyte)Xse.extract_epi8(this, (byte)index); + } + else + { + sbyte3 onStack = this; + + return *((sbyte*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -2302,7 +2328,17 @@ readonly get { Assert.IsWithinArrayBounds(index, 3); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi8(this, (byte)value, (byte)index); + } + else + { + sbyte3 onStack = this; + *((sbyte*)&onStack + index) = value; + + this = onStack; + } } } @@ -2530,21 +2566,7 @@ readonly get { if (Sse2.IsSse2Supported) { - if (Constant.IsConstantExpression(n) && n == 7) - { - return Sse2.cmpgt_epi8(Sse2.setzero_si128(), x); - } - else - { - if (Sse4_1.IsSse41Supported) - { - return (sbyte3)((short3)x >> n); - } - else - { - return Xse.srai_epi8(x, n); - } - } + return Xse.srai_epi8(x, n, 3); } else { @@ -2558,7 +2580,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); + v128 results = RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); + + return *(bool3*)&results; } else { @@ -2571,7 +2595,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmplt_epi8(left, right)); + v128 results = RegisterConversion.IsTrue8(Xse.cmplt_epi8(left, right)); + + return *(bool3*)&results; } else { @@ -2584,7 +2610,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Sse2.cmpgt_epi8(left, right)); + v128 results = RegisterConversion.IsTrue8(Sse2.cmpgt_epi8(left, right)); + + return *(bool3*)&results; } else { @@ -2598,7 +2626,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); + v128 results = RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); + + return *(bool3*)&results; } else { @@ -2611,7 +2641,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Sse2.cmpgt_epi8(left, right)); + v128 results = RegisterConversion.IsFalse8(Sse2.cmpgt_epi8(left, right)); + + return *(bool3*)&results; } else { @@ -2624,7 +2656,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Xse.cmplt_epi8(left, right)); + v128 results = RegisterConversion.IsFalse8(Xse.cmplt_epi8(left, right)); + + return *(bool3*)&results; } else { diff --git a/Runtime/Math Lib/Types/Vectors/byte/sbyte32.cs b/Runtime/Math Lib/Types/Vectors/byte/sbyte32.cs index d605325..9364c7e 100644 --- a/Runtime/Math Lib/Types/Vectors/byte/sbyte32.cs +++ b/Runtime/Math Lib/Types/Vectors/byte/sbyte32.cs @@ -89,8 +89,6 @@ public DebuggerProxy(sbyte32 v) } - [FieldOffset(0)] private fixed sbyte asArray[32]; - [FieldOffset(0)] internal sbyte16 _v16_0; [FieldOffset(16)] internal sbyte16 _v16_16; @@ -3629,7 +3627,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 0); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 0); } else { @@ -3674,7 +3672,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 1); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 1); } else { @@ -3719,7 +3717,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 2); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 2); } else { @@ -3764,7 +3762,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 3); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 3); } else { @@ -3809,7 +3807,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 4); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 4); } else { @@ -3854,7 +3852,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 5); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 5); } else { @@ -3899,7 +3897,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 6); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 6); } else { @@ -3944,7 +3942,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 7); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 7); } else { @@ -4017,7 +4015,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 8); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 8); } else { @@ -4071,7 +4069,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 9); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 9); } else { @@ -4125,11 +4123,11 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 10); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 10); } else if (Sse2.IsSse2Supported) { - this._v16_16 = Sse2.insert_epi16(this._v16_16, *(short*)&value, 2); + this._v16_16 = Xse.insert_epi16(this._v16_16, *(ushort*)&value, 2); } else { @@ -4184,11 +4182,11 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 11); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 11); } else if (Sse2.IsSse2Supported) { - this._v16_16 = Sse2.insert_epi16(this._v16_16, *(short*)&value, 3); + this._v16_16 = Xse.insert_epi16(this._v16_16, *(ushort*)&value, 3); } else { @@ -4241,7 +4239,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 12); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 12); } else { @@ -4295,7 +4293,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 13); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 13); } else { @@ -4349,7 +4347,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 14); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 14); } else { @@ -4403,7 +4401,7 @@ readonly get { if (Avx.IsAvxSupported) { - this = Avx.mm256_insert_epi16(this, *(short*)&value, 15); + this = Xse.mm256_insert_epi16(this, *(ushort*)&value, 15); } else { @@ -4416,10 +4414,11 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v256(sbyte32 input) => RegisterConversion.ToV256(input); + public static implicit operator v256(sbyte32 input) => new v256 { SByte0 = input.x0, SByte1 = input.x1, SByte2 = input.x2, SByte3 = input.x3, SByte4 = input.x4, SByte5 = input.x5, SByte6 = input.x6, SByte7 = input.x7, SByte8 = input.x8, SByte9 = input.x9, SByte10 = input.x10, SByte11 = input.x11, SByte12 = input.x12, SByte13 = input.x13, SByte14 = input.x14, SByte15 = input.x15, SByte16 = input.x16, SByte17 = input.x17, SByte18 = input.x18, SByte19 = input.x19, SByte20 = input.x20, SByte21 = input.x21, SByte22 = input.x22, SByte23 = input.x23, SByte24 = input.x24, SByte25 = input.x25, SByte26 = input.x26, SByte27 = input.x27, SByte28 = input.x28, SByte29 = input.x29, SByte30 = input.x30, SByte31 = input.x31 }; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator sbyte32(v256 input) => RegisterConversion.ToType(input); + public static implicit operator sbyte32(v256 input) => new sbyte32 { x0 = input.SByte0, x1 = input.SByte1, x2 = input.SByte2, x3 = input.SByte3, x4 = input.SByte4, x5 = input.SByte5, x6 = input.SByte6, x7 = input.SByte7, x8 = input.SByte8, x9 = input.SByte9, x10 = input.SByte10, x11 = input.SByte11, x12 = input.SByte12, x13 = input.SByte13, x14 = input.SByte14, x15 = input.SByte15, x16 = input.SByte16, x17 = input.SByte17, x18 = input.SByte18, x19 = input.SByte19, x20 = input.SByte20, x21 = input.SByte21, x22 = input.SByte22, x23 = input.SByte23, x24 = input.SByte24, x25 = input.SByte25, x26 = input.SByte26, x27 = input.SByte27, x28 = input.SByte28, x29 = input.SByte29, x30 = input.SByte30, x31 = input.SByte31 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator sbyte32(sbyte input) => new sbyte32(input); @@ -4450,7 +4449,28 @@ readonly get { Assert.IsWithinArrayBounds(index, 32); - return asArray[index]; + if (Avx2.IsAvx2Supported) + { + return (sbyte)Xse.mm256_extract_epi8(this, (byte)index); + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 16) + { + return (sbyte)Xse.extract_epi8(_v16_0, (byte)index); + } + else + { + return (sbyte)Xse.extract_epi8(_v16_16, (byte)(index - 16)); + } + } + } + + sbyte32 onStack = this; + + return *((sbyte*)&onStack + index); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -4458,7 +4478,32 @@ readonly get { Assert.IsWithinArrayBounds(index, 32); - asArray[index] = value; + if (Avx2.IsAvx2Supported) + { + this = Xse.mm256_insert_epi8(this, (byte)value, (byte)index); + + return; + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 16) + { + _v16_0 = Xse.insert_epi8(_v16_0, (byte)value, (byte)index); + } + else + { + _v16_16 = Xse.insert_epi8(_v16_16, (byte)value, (byte)(index - 16)); + } + + return; + } + } + + sbyte32 onStack = this; + *((sbyte*)&onStack + index) = value; + this = onStack; } } diff --git a/Runtime/Math Lib/Types/Vectors/byte/sbyte4.cs b/Runtime/Math Lib/Types/Vectors/byte/sbyte4.cs index a213a30..4efe18f 100644 --- a/Runtime/Math Lib/Types/Vectors/byte/sbyte4.cs +++ b/Runtime/Math Lib/Types/Vectors/byte/sbyte4.cs @@ -35,8 +35,6 @@ public DebuggerProxy(sbyte4 v) } - [FieldOffset(0)] private fixed sbyte asArray[4]; - [FieldOffset(0)] public sbyte x; [FieldOffset(1)] public sbyte y; [FieldOffset(2)] public sbyte z; @@ -5897,10 +5895,30 @@ public readonly sbyte2 ww [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(sbyte4 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(sbyte4 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.SByte0 = input.x; + result.SByte1 = input.y; + result.SByte2 = input.z; + result.SByte3 = input.w; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator sbyte4(v128 input) => RegisterConversion.ToType(input); + public static implicit operator sbyte4(v128 input) => new sbyte4 { x = input.SByte0, y = input.SByte1, z = input.SByte2, w = input.SByte3 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator sbyte4(sbyte input) => new sbyte4(input); @@ -6046,7 +6064,7 @@ public static implicit operator int4(sbyte4 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi8_epi32(input)); + return RegisterConversion.ToInt4(Xse.cvtepi8_epi32(input)); } else { @@ -6059,7 +6077,7 @@ public static explicit operator uint4(sbyte4 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi8_epi32(input)); + return RegisterConversion.ToUInt4(Xse.cvtepi8_epi32(input)); } else { @@ -6109,7 +6127,7 @@ public static implicit operator float4(sbyte4 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi8_ps(input)); + return RegisterConversion.ToFloat4(Xse.cvtepi8_ps(input)); } else { @@ -6128,7 +6146,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 4); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return (sbyte)Xse.extract_epi8(this, (byte)index); + } + else + { + sbyte4 onStack = this; + + return *((sbyte*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -6136,7 +6163,17 @@ readonly get { Assert.IsWithinArrayBounds(index, 4); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi8(this, (byte)value, (byte)index); + } + else + { + sbyte4 onStack = this; + *((sbyte*)&onStack + index) = value; + + this = onStack; + } } } @@ -6364,21 +6401,7 @@ readonly get { if (Sse2.IsSse2Supported) { - if (Constant.IsConstantExpression(n) && n == 7) - { - return Sse2.cmpgt_epi8(Sse2.setzero_si128(), x); - } - else - { - if (Sse4_1.IsSse41Supported) - { - return (sbyte4)((short4)x >> n); - } - else - { - return Xse.srai_epi8(x, n); - } - } + return Xse.srai_epi8(x, n, 4); } else { @@ -6392,7 +6415,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); + v128 results = RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); + + return *(bool4*)&results; } else { @@ -6405,7 +6430,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmplt_epi8(left, right)); + v128 results = RegisterConversion.IsTrue8(Xse.cmplt_epi8(left, right)); + + return *(bool4*)&results; } else { @@ -6418,7 +6445,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Sse2.cmpgt_epi8(left, right)); + v128 results = RegisterConversion.IsTrue8(Sse2.cmpgt_epi8(left, right)); + + return *(bool4*)&results; } else { @@ -6432,7 +6461,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); + v128 results = RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); + + return *(bool4*)&results; } else { @@ -6445,7 +6476,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Sse2.cmpgt_epi8(left, right)); + v128 results = RegisterConversion.IsFalse8(Sse2.cmpgt_epi8(left, right)); + + return *(bool4*)&results; } else { @@ -6458,7 +6491,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Xse.cmplt_epi8(left, right)); + v128 results = RegisterConversion.IsFalse8(Xse.cmplt_epi8(left, right)); + + return *(bool4*)&results; } else { diff --git a/Runtime/Math Lib/Types/Vectors/byte/sbyte8.cs b/Runtime/Math Lib/Types/Vectors/byte/sbyte8.cs index 6a00510..3c80ce0 100644 --- a/Runtime/Math Lib/Types/Vectors/byte/sbyte8.cs +++ b/Runtime/Math Lib/Types/Vectors/byte/sbyte8.cs @@ -43,9 +43,6 @@ public DebuggerProxy(sbyte8 v) } - [FieldOffset(0)] private fixed sbyte asArray[8]; - [FieldOffset(0)] private fixed ulong alias_long[1]; // somehow this unused line of code DE-confuses the compiler when writing back to memory - [FieldOffset(0)] public sbyte x0; [FieldOffset(1)] public sbyte x1; [FieldOffset(2)] public sbyte x2; @@ -651,7 +648,7 @@ readonly get } else if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 0); + this = Xse.insert_epi16(this, *(ushort*)&value, 0); } else { @@ -709,7 +706,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 1); + this = Xse.insert_epi16(this, *(ushort*)&value, 1); } else { @@ -767,7 +764,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 2); + this = Xse.insert_epi16(this, *(ushort*)&value, 2); } else { @@ -825,7 +822,7 @@ readonly get { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(this, *(short*)&value, 3); + this = Xse.insert_epi16(this, *(ushort*)&value, 3); } else { @@ -838,10 +835,48 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(sbyte8 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(sbyte8 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.SByte0 = input.x0; + result.SByte1 = input.x1; + result.SByte2 = input.x2; + result.SByte3 = input.x3; + result.SByte4 = input.x4; + result.SByte5 = input.x5; + result.SByte6 = input.x6; + result.SByte7 = input.x7; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator sbyte8(v128 input) => RegisterConversion.ToType(input); + public static implicit operator sbyte8(v128 input) + { + sbyte8 result; + + result.x0 = input.SByte0; + result.x1 = input.SByte1; + result.x2 = input.SByte2; + result.x3 = input.SByte3; + result.x4 = input.SByte4; + result.x5 = input.SByte5; + result.x6 = input.SByte6; + result.x7 = input.SByte7; + + return result; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator sbyte8(sbyte input) => new sbyte8(input); @@ -993,7 +1028,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 8); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return (sbyte)Xse.extract_epi8(this, (byte)index); + } + else + { + sbyte8 onStack = this; + + return *((sbyte*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1001,7 +1045,17 @@ readonly get { Assert.IsWithinArrayBounds(index, 8); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi8(this, (byte)value, (byte)index); + } + else + { + sbyte8 onStack = this; + *((sbyte*)&onStack + index) = value; + + this = onStack; + } } } @@ -1229,21 +1283,7 @@ readonly get { if (Sse2.IsSse2Supported) { - if (Constant.IsConstantExpression(n) && n == 7) - { - return Sse2.cmpgt_epi8(Sse2.setzero_si128(), x); - } - else - { - if (Sse4_1.IsSse41Supported) - { - return (sbyte8)((short8)x >> n); - } - else - { - return Xse.srai_epi8(x, n); - } - } + return Xse.srai_epi8(x, n, 8); } else { @@ -1257,7 +1297,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); + return RegisterConversion.IsTrue8(Sse2.cmpeq_epi8(left, right)); } else { @@ -1270,7 +1310,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Xse.cmplt_epi8(left, right)); + return RegisterConversion.IsTrue8(Xse.cmplt_epi8(left, right)); } else { @@ -1283,7 +1323,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(Sse2.cmpgt_epi8(left, right)); + return RegisterConversion.IsTrue8(Sse2.cmpgt_epi8(left, right)); } else { @@ -1297,7 +1337,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); + return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(left, right)); } else { @@ -1310,7 +1350,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Sse2.cmpgt_epi8(left, right)); + return RegisterConversion.IsFalse8(Sse2.cmpgt_epi8(left, right)); } else { @@ -1323,7 +1363,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse8(Xse.cmplt_epi8(left, right)); + return RegisterConversion.IsFalse8(Xse.cmplt_epi8(left, right)); } else { diff --git a/Runtime/Math Lib/Types/Vectors/float/float8.cs b/Runtime/Math Lib/Types/Vectors/float/float8.cs index c283d63..b6667a6 100644 --- a/Runtime/Math Lib/Types/Vectors/float/float8.cs +++ b/Runtime/Math Lib/Types/Vectors/float/float8.cs @@ -3,6 +3,7 @@ using System.Runtime.InteropServices; using Unity.Mathematics; using Unity.Burst.Intrinsics; +using Unity.Burst.CompilerServices; using MaxMath.Intrinsics; using DevTools; @@ -15,8 +16,6 @@ namespace MaxMath [StructLayout(LayoutKind.Explicit, Size = 8 * sizeof(float))] unsafe public struct float8 : IEquatable, IFormattable { - [FieldOffset(0)] private fixed float asArray[8]; - [FieldOffset(0)] internal float4 _v4_0; [FieldOffset(16)] internal float4 _v4_4; @@ -92,7 +91,7 @@ public float8(float2 x01, float3 x234, float3 x567) } - this = new float8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + this = new float8(RegisterConversion.ToFloat4(lo), RegisterConversion.ToFloat4(hi)); } else { @@ -118,7 +117,7 @@ public float8(float3 x012, float2 x34, float3 x567) hi = Sse4_1.blend_ps(mid, hi, 0b1110); - this = new float8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + this = new float8(RegisterConversion.ToFloat4(lo), RegisterConversion.ToFloat4(hi)); } else if (Sse2.IsSse2Supported) { @@ -131,7 +130,7 @@ public float8(float3 x012, float2 x34, float3 x567) hi = Xse.blendv_ps(mid, hi, new v128(0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255)); - this = new float8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + this = new float8(RegisterConversion.ToFloat4(lo), RegisterConversion.ToFloat4(hi)); } else { @@ -164,7 +163,7 @@ public float8(float3 x012, float3 x345, float2 x67) } - this = new float8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + this = new float8(RegisterConversion.ToFloat4(lo), RegisterConversion.ToFloat4(hi)); } else { @@ -191,7 +190,7 @@ public float8(float2 x01, float4 x2345, float2 x67) v128 hi = Sse2.bslli_si128(RegisterConversion.ToV128(x67), 2 * sizeof(float)); hi = Sse2.unpackhi_pd(RegisterConversion.ToV128(x2345), hi); - this = new float8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + this = new float8(RegisterConversion.ToFloat4(lo), RegisterConversion.ToFloat4(hi)); } else { @@ -235,7 +234,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Avx.mm256_castps256_ps128(this)); + return RegisterConversion.ToFloat4(Avx.mm256_castps256_ps128(this)); } else { @@ -263,7 +262,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Ssse3.alignr_epi8(Avx.mm256_castps256_ps128(this), Avx.mm256_extractf128_ps(this, 1), 1 * sizeof(float))); + return RegisterConversion.ToFloat4(Ssse3.alignr_epi8(Avx.mm256_castps256_ps128(this), Avx.mm256_extractf128_ps(this, 1), 1 * sizeof(float))); } else { @@ -302,7 +301,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx.mm256_castps256_ps128(Avx2.mm256_permute4x64_pd(this, Sse.SHUFFLE(0, 0, 2, 1)))); + return RegisterConversion.ToFloat4(Avx.mm256_castps256_ps128(Avx2.mm256_permute4x64_pd(this, Sse.SHUFFLE(0, 0, 2, 1)))); } else { @@ -341,7 +340,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Ssse3.alignr_epi8(Avx.mm256_castps256_ps128(this), Avx.mm256_extractf128_ps(this, 1), 3 * sizeof(float))); + return RegisterConversion.ToFloat4(Ssse3.alignr_epi8(Avx.mm256_castps256_ps128(this), Avx.mm256_extractf128_ps(this, 1), 3 * sizeof(float))); } else { @@ -380,7 +379,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Avx.mm256_extractf128_ps(this, 1)); + return RegisterConversion.ToFloat4(Avx.mm256_extractf128_ps(this, 1)); } else { @@ -409,7 +408,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Avx.mm256_castps256_ps128(this)); + return RegisterConversion.ToFloat3(Avx.mm256_castps256_ps128(this)); } else { @@ -437,7 +436,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Sse2.bsrli_si128(Avx.mm256_castps256_ps128(this), sizeof(float))); + return RegisterConversion.ToFloat3(Sse2.bsrli_si128(Avx.mm256_castps256_ps128(this), sizeof(float))); } else { @@ -465,7 +464,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx.mm256_castps256_ps128(Avx2.mm256_permute4x64_pd(this, Sse.SHUFFLE(0, 0, 2, 1)))); + return RegisterConversion.ToFloat3(Avx.mm256_castps256_ps128(Avx2.mm256_permute4x64_pd(this, Sse.SHUFFLE(0, 0, 2, 1)))); } else { @@ -494,7 +493,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Ssse3.alignr_epi8(Avx.mm256_castps256_ps128(this), Avx.mm256_extractf128_ps(this, 1), 3 * sizeof(float))); + return RegisterConversion.ToFloat3(Ssse3.alignr_epi8(Avx.mm256_castps256_ps128(this), Avx.mm256_extractf128_ps(this, 1), 3 * sizeof(float))); } else { @@ -523,7 +522,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Avx.mm256_extractf128_ps(this, 1)); + return RegisterConversion.ToFloat3(Avx.mm256_extractf128_ps(this, 1)); } else { @@ -551,7 +550,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Sse2.bsrli_si128(Avx.mm256_extractf128_ps(this, 1), 1 * sizeof(float))); + return RegisterConversion.ToFloat3(Sse2.bsrli_si128(Avx.mm256_extractf128_ps(this, 1), 1 * sizeof(float))); } else { @@ -580,7 +579,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Avx.mm256_castps256_ps128(this)); + return RegisterConversion.ToFloat2(Avx.mm256_castps256_ps128(this)); } else { @@ -608,7 +607,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Sse2.bsrli_si128(Avx.mm256_castps256_ps128(this), sizeof(float))); + return RegisterConversion.ToFloat2(Sse2.bsrli_si128(Avx.mm256_castps256_ps128(this), sizeof(float))); } else { @@ -636,7 +635,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Sse2.bsrli_si128(Avx.mm256_castps256_ps128(this), 2 * sizeof(float))); + return RegisterConversion.ToFloat2(Sse2.bsrli_si128(Avx.mm256_castps256_ps128(this), 2 * sizeof(float))); } else { @@ -664,7 +663,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Ssse3.alignr_epi8(Avx.mm256_castps256_ps128(this), Avx.mm256_extractf128_ps(this, 1), 3 * sizeof(float))); + return RegisterConversion.ToFloat2(Ssse3.alignr_epi8(Avx.mm256_castps256_ps128(this), Avx.mm256_extractf128_ps(this, 1), 3 * sizeof(float))); } else { @@ -693,7 +692,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Avx.mm256_extractf128_ps(this, 1)); + return RegisterConversion.ToFloat2(Avx.mm256_extractf128_ps(this, 1)); } else { @@ -721,7 +720,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Sse2.bsrli_si128(Avx.mm256_extractf128_ps(this, 1), 1 * sizeof(float))); + return RegisterConversion.ToFloat2(Sse2.bsrli_si128(Avx.mm256_extractf128_ps(this, 1), 1 * sizeof(float))); } else { @@ -749,7 +748,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx.mm256_castps256_ps128(Avx2.mm256_permute4x64_pd(this, Sse.SHUFFLE(0, 0, 0, 3)))); + return RegisterConversion.ToFloat2(Avx.mm256_castps256_ps128(Avx2.mm256_permute4x64_pd(this, Sse.SHUFFLE(0, 0, 0, 3)))); } else { @@ -774,10 +773,11 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v256(float8 input) => RegisterConversion.ToV256(input); + public static implicit operator v256(float8 input) => new v256(input.x0, input.x1, input.x2, input.x3, input.x4, input.x5, input.x6, input.x7); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator float8(v256 input) => RegisterConversion.ToType(input); + public static implicit operator float8(v256 input) => new float8{ x0 = input.Float0, x1 = input.Float1, x2 = input.Float2, x3 = input.Float3, x4 = input.Float4, x5 = input.Float5, x6 = input.Float6, x7 = input.Float7 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator float8(quarter input) => new float8((float)input); @@ -796,15 +796,61 @@ readonly get { Assert.IsWithinArrayBounds(index, 8); - return asArray[index]; + if (Avx.IsAvxSupported) + { + return Xse.mm256_extract_ps(this, (byte)index); + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 4) + { + return Xse.extract_ps(RegisterConversion.ToV128(_v4_0), (byte)index); + } + else + { + return Xse.extract_ps(RegisterConversion.ToV128(_v4_4), (byte)(index - 4)); + } + } + } + + float8 onStack = this; + + return *((float*)&onStack + index); } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { Assert.IsWithinArrayBounds(index, 8); + + if (Avx.IsAvxSupported) + { + this = Xse.mm256_insert_ps(this, value, (byte)index); + + return; + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 4) + { + _v4_0 = RegisterConversion.ToFloat4(Xse.insert_ps(RegisterConversion.ToV128(_v4_0), value, (byte)index)); + } + else + { + _v4_4 = RegisterConversion.ToFloat4(Xse.insert_ps(RegisterConversion.ToV128(_v4_4), value, (byte)(index - 4))); + } + + return; + } + } - asArray[index] = value; + float8 onStack = this; + *((float*)&onStack + index) = value; + this = onStack; } } diff --git a/Runtime/Math Lib/Types/Vectors/half/half8.cs b/Runtime/Math Lib/Types/Vectors/half/half8.cs index bfd8c87..eddce63 100644 --- a/Runtime/Math Lib/Types/Vectors/half/half8.cs +++ b/Runtime/Math Lib/Types/Vectors/half/half8.cs @@ -1,9 +1,13 @@ +//#define TESTING + + using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Unity.Mathematics; using Unity.Burst.Intrinsics; +using MaxMath.Intrinsics; using DevTools; using static Unity.Burst.Intrinsics.X86; @@ -40,8 +44,6 @@ public DebuggerProxy(half8 v) } - [FieldOffset(0)] private fixed ushort asArray[8]; - [FieldOffset(0)] public half x0; [FieldOffset(2)] public half x1; [FieldOffset(4)] public half x2; @@ -139,14 +141,21 @@ public half8(half4 x0123, half4 x4567) [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(half8 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(half8 input) => new v128 { UShort0 = input.x0.value, UShort1 = input.x1.value, UShort2 = input.x2.value, UShort3 = input.x3.value, UShort4 = input.x4.value, UShort5 = input.x5.value, UShort6 = input.x6.value, UShort7 = input.x7.value }; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator half8(v128 input) => RegisterConversion.ToType(input); + public static implicit operator half8(v128 input) => new half8 { x0 = maxmath.ashalf(input.UShort0), x1 = maxmath.ashalf(input.UShort1), x2 = maxmath.ashalf(input.UShort2), x3 = maxmath.ashalf(input.UShort3), x4 = maxmath.ashalf(input.UShort4), x5 = maxmath.ashalf(input.UShort5), x6 = maxmath.ashalf(input.UShort6), x7 = maxmath.ashalf(input.UShort7) }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator half8(half input) => new half8(input); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator half8(float input) => (half)input; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator half8(double input) => (half)input; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static explicit operator half8(float8 input) @@ -164,14 +173,16 @@ public static explicit operator half8(float8 input) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator float8(half8 input) { - //if (F16C.IsF16CSupported) - //{ - // return F16C.mm256_cvtph_ps(input); - //} - //else - //{ +#if !TESTING + if (F16C.IsF16CSupported) + { + return F16C.mm256_cvtph_ps(input); + } + else +#endif + { return new float8((float4)input.v4_0, (float4)input.v4_4); - //} + } } @@ -182,15 +193,32 @@ readonly get { Assert.IsWithinArrayBounds(index, 8); - return maxmath.ashalf(asArray[index]); + if (Sse2.IsSse2Supported) + { + return maxmath.ashalf(Xse.extract_epi16(this, (byte)index)); + } + else + { + half8 onStack = this; + return *((half*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { Assert.IsWithinArrayBounds(index, 8); - - asArray[index] = maxmath.asushort(value); + + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi16(this, maxmath.asushort(value), (byte)index); + } + else + { + half8 onStack = this; + *((half*)&onStack + index) = value; + this = onStack; + } } } @@ -200,7 +228,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); + return RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); } else { @@ -213,7 +241,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); + return RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); } else { diff --git a/Runtime/Math Lib/Types/Vectors/int/int8.cs b/Runtime/Math Lib/Types/Vectors/int/int8.cs index 8c08de4..3290f8f 100644 --- a/Runtime/Math Lib/Types/Vectors/int/int8.cs +++ b/Runtime/Math Lib/Types/Vectors/int/int8.cs @@ -43,8 +43,6 @@ public DebuggerProxy(int8 v) } - [FieldOffset(0)] private fixed int asArray[8]; - [FieldOffset(0)] internal int4 _v4_0; [FieldOffset(16)] internal int4 _v4_4; @@ -111,7 +109,7 @@ public int8(int2 x01, int3 x234, int3 x567) v128 hi = Sse2.bslli_si128(RegisterConversion.ToV128(x567), sizeof(int)); hi = Xse.blend_epi16(mid, hi, 0b1111_1100); - this = new int8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + this = new int8(RegisterConversion.ToInt4(lo), RegisterConversion.ToInt4(hi)); } else { @@ -135,7 +133,7 @@ public int8(int3 x012, int2 x34, int3 x567) v128 hi = Sse2.bslli_si128(RegisterConversion.ToV128(x567), sizeof(int)); hi = Xse.blend_epi16(mid, hi, 0b1111_1100); - this = new int8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + this = new int8(RegisterConversion.ToInt4(lo), RegisterConversion.ToInt4(hi)); } else { @@ -159,7 +157,7 @@ public int8(int3 x012, int3 x345, int2 x67) v128 lo = Xse.blend_epi16(RegisterConversion.ToV128(x012), mid, 0b1100_0000); - this = new int8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + this = new int8(RegisterConversion.ToInt4(lo), RegisterConversion.ToInt4(hi)); } else { @@ -186,7 +184,7 @@ public int8(int2 x01, int4 x2345, int2 x67) v128 hi = Sse2.bslli_si128(RegisterConversion.ToV128(x67), 2 * sizeof(int)); hi = Sse2.unpackhi_epi64(RegisterConversion.ToV128(x2345), hi); - this = new int8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + this = new int8(RegisterConversion.ToInt4(lo), RegisterConversion.ToInt4(hi)); } else { @@ -230,7 +228,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Avx.mm256_castsi256_si128(this)); + return RegisterConversion.ToInt4(Avx.mm256_castsi256_si128(this)); } else { @@ -258,14 +256,14 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Ssse3.alignr_epi8(Avx.mm256_castsi256_si128(this), Avx2.mm256_extracti128_si256(this, 1), 1 * sizeof(int))); + return RegisterConversion.ToInt4(Ssse3.alignr_epi8(Avx.mm256_castsi256_si128(this), Avx2.mm256_extracti128_si256(this, 1), 1 * sizeof(int))); } else if (Ssse3.IsSsse3Supported) { int4 lo = this._v4_0; int4 hi = this._v4_4; - return RegisterConversion.ToType(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 1 * sizeof(int))); + return RegisterConversion.ToInt4(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 1 * sizeof(int))); } else { @@ -304,14 +302,14 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx.mm256_castsi256_si128(Avx2.mm256_permute4x64_epi64(this, Sse.SHUFFLE(0, 0, 2, 1)))); + return RegisterConversion.ToInt4(Avx.mm256_castsi256_si128(Avx2.mm256_permute4x64_epi64(this, Sse.SHUFFLE(0, 0, 2, 1)))); } else if (Ssse3.IsSsse3Supported) { int4 lo = this._v4_0; int4 hi = this._v4_4; - return RegisterConversion.ToType(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 2 * sizeof(int))); + return RegisterConversion.ToInt4(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 2 * sizeof(int))); } else { @@ -350,14 +348,14 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Ssse3.alignr_epi8(Avx.mm256_castsi256_si128(this), Avx2.mm256_extracti128_si256(this, 1), 3 * sizeof(int))); + return RegisterConversion.ToInt4(Ssse3.alignr_epi8(Avx.mm256_castsi256_si128(this), Avx2.mm256_extracti128_si256(this, 1), 3 * sizeof(int))); } else if (Ssse3.IsSsse3Supported) { int4 lo = this._v4_0; int4 hi = this._v4_4; - return RegisterConversion.ToType(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 3 * sizeof(int))); + return RegisterConversion.ToInt4(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 3 * sizeof(int))); } else { @@ -396,7 +394,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx2.mm256_extracti128_si256(this, 1)); + return RegisterConversion.ToInt4(Avx2.mm256_extracti128_si256(this, 1)); } else { @@ -425,7 +423,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Avx.mm256_castsi256_si128(this)); + return RegisterConversion.ToInt3(Avx.mm256_castsi256_si128(this)); } else { @@ -453,7 +451,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Sse2.bsrli_si128(Avx.mm256_castsi256_si128(this), sizeof(int))); + return RegisterConversion.ToInt3(Sse2.bsrli_si128(Avx.mm256_castsi256_si128(this), sizeof(int))); } else { @@ -481,14 +479,14 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx.mm256_castsi256_si128(Avx2.mm256_permute4x64_epi64(this, Sse.SHUFFLE(0, 0, 2, 1)))); + return RegisterConversion.ToInt3(Avx.mm256_castsi256_si128(Avx2.mm256_permute4x64_epi64(this, Sse.SHUFFLE(0, 0, 2, 1)))); } else if (Ssse3.IsSsse3Supported) { int4 lo = this._v4_0; int4 hi = this._v4_4; - return RegisterConversion.ToType(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 2 * sizeof(int))); + return RegisterConversion.ToInt3(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 2 * sizeof(int))); } else { @@ -517,14 +515,14 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Ssse3.alignr_epi8(Avx.mm256_castsi256_si128(this), Avx2.mm256_extracti128_si256(this, 1), 3 * sizeof(int))); + return RegisterConversion.ToInt3(Ssse3.alignr_epi8(Avx.mm256_castsi256_si128(this), Avx2.mm256_extracti128_si256(this, 1), 3 * sizeof(int))); } else if (Ssse3.IsSsse3Supported) { int4 lo = this._v4_0; int4 hi = this._v4_4; - return RegisterConversion.ToType(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 3 * sizeof(int))); + return RegisterConversion.ToInt3(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 3 * sizeof(int))); } else { @@ -553,7 +551,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx2.mm256_extracti128_si256(this, 1)); + return RegisterConversion.ToInt3(Avx2.mm256_extracti128_si256(this, 1)); } else { @@ -581,7 +579,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Sse2.bsrli_si128(Avx2.mm256_extracti128_si256(this, 1), 1 * sizeof(int))); + return RegisterConversion.ToInt3(Sse2.bsrli_si128(Avx2.mm256_extracti128_si256(this, 1), 1 * sizeof(int))); } else { @@ -610,7 +608,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Avx.mm256_castsi256_si128(this)); + return RegisterConversion.ToInt2(Avx.mm256_castsi256_si128(this)); } else { @@ -638,7 +636,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Sse2.bsrli_si128(Avx.mm256_castsi256_si128(this), sizeof(int))); + return RegisterConversion.ToInt2(Sse2.bsrli_si128(Avx.mm256_castsi256_si128(this), sizeof(int))); } else { @@ -666,7 +664,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Sse2.bsrli_si128(Avx.mm256_castsi256_si128(this), 2 * sizeof(int))); + return RegisterConversion.ToInt2(Sse2.bsrli_si128(Avx.mm256_castsi256_si128(this), 2 * sizeof(int))); } else { @@ -694,14 +692,14 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Ssse3.alignr_epi8(Avx.mm256_castsi256_si128(this), Avx2.mm256_extracti128_si256(this, 1), 3 * sizeof(int))); + return RegisterConversion.ToInt2(Ssse3.alignr_epi8(Avx.mm256_castsi256_si128(this), Avx2.mm256_extracti128_si256(this, 1), 3 * sizeof(int))); } else if (Ssse3.IsSsse3Supported) { int4 lo = this._v4_0; int4 hi = this._v4_4; - return RegisterConversion.ToType(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 3 * sizeof(int))); + return RegisterConversion.ToInt2(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 3 * sizeof(int))); } else { @@ -730,7 +728,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx2.mm256_extracti128_si256(this, 1)); + return RegisterConversion.ToInt2(Avx2.mm256_extracti128_si256(this, 1)); } else { @@ -758,7 +756,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Sse2.bsrli_si128(Avx2.mm256_extracti128_si256(this, 1), 1 * sizeof(int))); + return RegisterConversion.ToInt2(Sse2.bsrli_si128(Avx2.mm256_extracti128_si256(this, 1), 1 * sizeof(int))); } else { @@ -786,7 +784,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx.mm256_castsi256_si128(Avx2.mm256_permute4x64_epi64(this, Sse.SHUFFLE(0, 0, 0, 3)))); + return RegisterConversion.ToInt2(Avx.mm256_castsi256_si128(Avx2.mm256_permute4x64_epi64(this, Sse.SHUFFLE(0, 0, 0, 3)))); } else { @@ -811,10 +809,11 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v256(int8 input) => RegisterConversion.ToV256(input); + public static implicit operator v256(int8 input) => new v256(input.x0, input.x1, input.x2, input.x3, input.x4, input.x5, input.x6, input.x7); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator int8(v256 input) => RegisterConversion.ToType(input); + public static implicit operator int8(v256 input) => new int8{ x0 = input.SInt0, x1 = input.SInt1, x2 = input.SInt2, x3 = input.SInt3, x4 = input.SInt4, x5 = input.SInt5, x6 = input.SInt6, x7 = input.SInt7 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator int8(int input) => new int8(input); @@ -877,15 +876,61 @@ readonly get { Assert.IsWithinArrayBounds(index, 8); - return asArray[index]; + if (Avx2.IsAvx2Supported) + { + return (int)Xse.mm256_extract_epi32(this, (byte)index); + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 4) + { + return (int)Xse.extract_epi32(RegisterConversion.ToV128(_v4_0), (byte)index); + } + else + { + return (int)Xse.extract_epi32(RegisterConversion.ToV128(_v4_4), (byte)(index - 4)); + } + } + } + + int8 onStack = this; + + return *((int*)&onStack + index); } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { Assert.IsWithinArrayBounds(index, 8); + + if (Avx2.IsAvx2Supported) + { + this = Xse.mm256_insert_epi32(this, (uint)value, (byte)index); + + return; + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 4) + { + _v4_0 = RegisterConversion.ToInt4(Xse.insert_epi32(RegisterConversion.ToV128(_v4_0), (uint)value, (byte)index)); + } + else + { + _v4_4 = RegisterConversion.ToInt4(Xse.insert_epi32(RegisterConversion.ToV128(_v4_4), (uint)value, (byte)(index - 4))); + } + + return; + } + } - asArray[index] = value; + int8 onStack = this; + *((int*)&onStack + index) = value; + this = onStack; } } @@ -952,8 +997,8 @@ readonly get } else if (Sse2.IsSse2Supported) { - return new int8(RegisterConversion.ToType(Xse.div_epi32(RegisterConversion.ToV128(left.v4_0), RegisterConversion.ToV128(right.v4_0))), - RegisterConversion.ToType(Xse.div_epi32(RegisterConversion.ToV128(left.v4_4), RegisterConversion.ToV128(right.v4_4)))); + return new int8(RegisterConversion.ToInt4(Xse.div_epi32(RegisterConversion.ToV128(left.v4_0), RegisterConversion.ToV128(right.v4_0))), + RegisterConversion.ToInt4(Xse.div_epi32(RegisterConversion.ToV128(left.v4_4), RegisterConversion.ToV128(right.v4_4)))); } else { @@ -970,8 +1015,8 @@ readonly get } else if (Sse2.IsSse2Supported) { - return new int8(RegisterConversion.ToType(Xse.rem_epi32(RegisterConversion.ToV128(left.v4_0), RegisterConversion.ToV128(right.v4_0))), - RegisterConversion.ToType(Xse.rem_epi32(RegisterConversion.ToV128(left.v4_4), RegisterConversion.ToV128(right.v4_4)))); + return new int8(RegisterConversion.ToInt4(Xse.rem_epi32(RegisterConversion.ToV128(left.v4_0), RegisterConversion.ToV128(right.v4_0))), + RegisterConversion.ToInt4(Xse.rem_epi32(RegisterConversion.ToV128(left.v4_4), RegisterConversion.ToV128(right.v4_4)))); } else { diff --git a/Runtime/Math Lib/Types/Vectors/int/uint8.cs b/Runtime/Math Lib/Types/Vectors/int/uint8.cs index 4f6d1fe..0452b10 100644 --- a/Runtime/Math Lib/Types/Vectors/int/uint8.cs +++ b/Runtime/Math Lib/Types/Vectors/int/uint8.cs @@ -43,8 +43,6 @@ public DebuggerProxy(uint8 v) } - [FieldOffset(0)] private fixed uint asArray[8]; - [FieldOffset(0)] internal uint4 _v4_0; [FieldOffset(16)] internal uint4 _v4_4; @@ -112,7 +110,7 @@ public uint8(uint2 x01, uint3 x234, uint3 x567) hi = Xse.blend_epi16(mid, hi, 0b1111_1100); - this = new uint8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + this = new uint8(RegisterConversion.ToUInt4(lo), RegisterConversion.ToUInt4(hi)); } else { @@ -137,7 +135,7 @@ public uint8(uint3 x012, uint2 x34, uint3 x567) v128 hi = Sse2.bslli_si128(RegisterConversion.ToV128(x567), sizeof(uint)); hi = Xse.blend_epi16(mid, hi, 0b1111_1100); - this = new uint8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + this = new uint8(RegisterConversion.ToUInt4(lo), RegisterConversion.ToUInt4(hi)); } else { @@ -161,7 +159,7 @@ public uint8(uint3 x012, uint3 x345, uint2 x67) mid = Sse2.bslli_si128(RegisterConversion.ToV128(x345), 3 * sizeof(uint)); v128 lo = Xse.blend_epi16(RegisterConversion.ToV128(x012), mid, 0b1100_0000); - this = new uint8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + this = new uint8(RegisterConversion.ToUInt4(lo), RegisterConversion.ToUInt4(hi)); } else { @@ -188,7 +186,7 @@ public uint8(uint2 x01, uint4 x2345, uint2 x67) v128 hi = Sse2.bslli_si128(RegisterConversion.ToV128(x67), 2 * sizeof(uint)); hi = Sse2.unpackhi_epi64(RegisterConversion.ToV128(x2345), hi); - this = new uint8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + this = new uint8(RegisterConversion.ToUInt4(lo), RegisterConversion.ToUInt4(hi)); } else { @@ -232,7 +230,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Avx.mm256_castsi256_si128(this)); + return RegisterConversion.ToUInt4(Avx.mm256_castsi256_si128(this)); } else { @@ -260,14 +258,14 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Ssse3.alignr_epi8(Avx.mm256_castsi256_si128(this), Avx2.mm256_extracti128_si256(this, 1), 1 * sizeof(uint))); + return RegisterConversion.ToUInt4(Ssse3.alignr_epi8(Avx.mm256_castsi256_si128(this), Avx2.mm256_extracti128_si256(this, 1), 1 * sizeof(uint))); } else if (Ssse3.IsSsse3Supported) { uint4 lo = this._v4_0; uint4 hi = this._v4_4; - return RegisterConversion.ToType(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 1 * sizeof(uint))); + return RegisterConversion.ToUInt4(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 1 * sizeof(uint))); } else { @@ -306,14 +304,14 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx.mm256_castsi256_si128(Avx2.mm256_permute4x64_epi64(this, Sse.SHUFFLE(0, 0, 2, 1)))); + return RegisterConversion.ToUInt4(Avx.mm256_castsi256_si128(Avx2.mm256_permute4x64_epi64(this, Sse.SHUFFLE(0, 0, 2, 1)))); } else if (Ssse3.IsSsse3Supported) { uint4 lo = this._v4_0; uint4 hi = this._v4_4; - return RegisterConversion.ToType(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 2 * sizeof(uint))); + return RegisterConversion.ToUInt4(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 2 * sizeof(uint))); } else { @@ -352,14 +350,14 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Ssse3.alignr_epi8(Avx.mm256_castsi256_si128(this), Avx2.mm256_extracti128_si256(this, 1), 3 * sizeof(uint))); + return RegisterConversion.ToUInt4(Ssse3.alignr_epi8(Avx.mm256_castsi256_si128(this), Avx2.mm256_extracti128_si256(this, 1), 3 * sizeof(uint))); } else if (Ssse3.IsSsse3Supported) { uint4 lo = this._v4_0; uint4 hi = this._v4_4; - return RegisterConversion.ToType(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 3 * sizeof(uint))); + return RegisterConversion.ToUInt4(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 3 * sizeof(uint))); } else { @@ -398,7 +396,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx2.mm256_extracti128_si256(this, 1)); + return RegisterConversion.ToUInt4(Avx2.mm256_extracti128_si256(this, 1)); } else { @@ -427,7 +425,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Avx.mm256_castsi256_si128(this)); + return RegisterConversion.ToUInt3(Avx.mm256_castsi256_si128(this)); } else { @@ -455,7 +453,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Sse2.bsrli_si128(Avx.mm256_castsi256_si128(this), sizeof(uint))); + return RegisterConversion.ToUInt3(Sse2.bsrli_si128(Avx.mm256_castsi256_si128(this), sizeof(uint))); } else { @@ -483,14 +481,14 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx.mm256_castsi256_si128(Avx2.mm256_permute4x64_epi64(this, Sse.SHUFFLE(0, 0, 2, 1)))); + return RegisterConversion.ToUInt3(Avx.mm256_castsi256_si128(Avx2.mm256_permute4x64_epi64(this, Sse.SHUFFLE(0, 0, 2, 1)))); } else if (Ssse3.IsSsse3Supported) { uint4 lo = this._v4_0; uint4 hi = this._v4_4; - return RegisterConversion.ToType(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 2 * sizeof(uint))); + return RegisterConversion.ToUInt3(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 2 * sizeof(uint))); } else { @@ -519,14 +517,14 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Ssse3.alignr_epi8(Avx.mm256_castsi256_si128(this), Avx2.mm256_extracti128_si256(this, 1), 3 * sizeof(uint))); + return RegisterConversion.ToUInt3(Ssse3.alignr_epi8(Avx.mm256_castsi256_si128(this), Avx2.mm256_extracti128_si256(this, 1), 3 * sizeof(uint))); } else if (Ssse3.IsSsse3Supported) { uint4 lo = this._v4_0; uint4 hi = this._v4_4; - return RegisterConversion.ToType(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 3 * sizeof(uint))); + return RegisterConversion.ToUInt3(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 3 * sizeof(uint))); } else { @@ -555,7 +553,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx2.mm256_extracti128_si256(this, 1)); + return RegisterConversion.ToUInt3(Avx2.mm256_extracti128_si256(this, 1)); } else { @@ -583,7 +581,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Sse2.bsrli_si128(Avx2.mm256_extracti128_si256(this, 1), 1 * sizeof(uint))); + return RegisterConversion.ToUInt3(Sse2.bsrli_si128(Avx2.mm256_extracti128_si256(this, 1), 1 * sizeof(uint))); } else { @@ -612,7 +610,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Avx.mm256_castsi256_si128(this)); + return RegisterConversion.ToUInt2(Avx.mm256_castsi256_si128(this)); } else { @@ -640,7 +638,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Sse2.bsrli_si128(Avx.mm256_castsi256_si128(this), sizeof(uint))); + return RegisterConversion.ToUInt2(Sse2.bsrli_si128(Avx.mm256_castsi256_si128(this), sizeof(uint))); } else { @@ -668,7 +666,7 @@ readonly get { if (Avx.IsAvxSupported) { - return RegisterConversion.ToType(Sse2.bsrli_si128(Avx.mm256_castsi256_si128(this), 2 * sizeof(uint))); + return RegisterConversion.ToUInt2(Sse2.bsrli_si128(Avx.mm256_castsi256_si128(this), 2 * sizeof(uint))); } else { @@ -696,14 +694,14 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Ssse3.alignr_epi8(Avx.mm256_castsi256_si128(this), Avx2.mm256_extracti128_si256(this, 1), 3 * sizeof(uint))); + return RegisterConversion.ToUInt2(Ssse3.alignr_epi8(Avx.mm256_castsi256_si128(this), Avx2.mm256_extracti128_si256(this, 1), 3 * sizeof(uint))); } else if (Ssse3.IsSsse3Supported) { uint4 lo = this._v4_0; uint4 hi = this._v4_4; - return RegisterConversion.ToType(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 3 * sizeof(uint))); + return RegisterConversion.ToUInt2(Ssse3.alignr_epi8(RegisterConversion.ToV128(lo), RegisterConversion.ToV128(hi), 3 * sizeof(uint))); } else { @@ -732,7 +730,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx2.mm256_extracti128_si256(this, 1)); + return RegisterConversion.ToUInt2(Avx2.mm256_extracti128_si256(this, 1)); } else { @@ -760,7 +758,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Sse2.bsrli_si128(Avx2.mm256_extracti128_si256(this, 1), 1 * sizeof(uint))); + return RegisterConversion.ToUInt2(Sse2.bsrli_si128(Avx2.mm256_extracti128_si256(this, 1), 1 * sizeof(uint))); } else { @@ -788,7 +786,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Avx.mm256_castsi256_si128(Avx2.mm256_permute4x64_epi64(this, Sse.SHUFFLE(0, 0, 0, 3)))); + return RegisterConversion.ToUInt2(Avx.mm256_castsi256_si128(Avx2.mm256_permute4x64_epi64(this, Sse.SHUFFLE(0, 0, 0, 3)))); } else { @@ -813,10 +811,11 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v256(uint8 input) => RegisterConversion.ToV256(input); + public static implicit operator v256(uint8 input) => new v256(input.x0, input.x1, input.x2, input.x3, input.x4, input.x5, input.x6, input.x7); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator uint8(v256 input) => RegisterConversion.ToType(input); + public static implicit operator uint8(v256 input) => new uint8{ x0 = input.UInt0, x1 = input.UInt1, x2 = input.UInt2, x3 = input.UInt3, x4 = input.UInt4, x5 = input.UInt5, x6 = input.UInt6, x7 = input.UInt7 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator uint8(uint input) => new uint8(input); @@ -869,15 +868,61 @@ readonly get { Assert.IsWithinArrayBounds(index, 8); - return asArray[index]; + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_extract_epi32(this, (byte)index); + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 4) + { + return Xse.extract_epi32(RegisterConversion.ToV128(_v4_0), (byte)index); + } + else + { + return Xse.extract_epi32(RegisterConversion.ToV128(_v4_4), (byte)(index - 4)); + } + } + } + + uint8 onStack = this; + + return *((uint*)&onStack + index); } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { Assert.IsWithinArrayBounds(index, 8); + + if (Avx2.IsAvx2Supported) + { + this = Xse.mm256_insert_epi32(this, value, (byte)index); + + return; + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 4) + { + _v4_0 = RegisterConversion.ToUInt4(Xse.insert_epi32(RegisterConversion.ToV128(_v4_0), value, (byte)index)); + } + else + { + _v4_4 = RegisterConversion.ToUInt4(Xse.insert_epi32(RegisterConversion.ToV128(_v4_4), value, (byte)(index - 4))); + } + + return; + } + } - asArray[index] = value; + uint8 onStack = this; + *((uint*)&onStack + index) = value; + this = onStack; } } @@ -939,8 +984,8 @@ readonly get } else if (Sse2.IsSse2Supported) { - return new uint8(RegisterConversion.ToType(Xse.div_epu32(RegisterConversion.ToV128(left.v4_0), RegisterConversion.ToV128(right.v4_0))), - RegisterConversion.ToType(Xse.div_epu32(RegisterConversion.ToV128(left.v4_4), RegisterConversion.ToV128(right.v4_4)))); + return new uint8(RegisterConversion.ToUInt4(Xse.div_epu32(RegisterConversion.ToV128(left.v4_0), RegisterConversion.ToV128(right.v4_0))), + RegisterConversion.ToUInt4(Xse.div_epu32(RegisterConversion.ToV128(left.v4_4), RegisterConversion.ToV128(right.v4_4)))); } else { @@ -966,8 +1011,8 @@ readonly get } else if (Sse2.IsSse2Supported) { - return new uint8(RegisterConversion.ToType(Xse.rem_epu32(RegisterConversion.ToV128(left.v4_0), RegisterConversion.ToV128(right.v4_0))), - RegisterConversion.ToType(Xse.rem_epu32(RegisterConversion.ToV128(left.v4_4), RegisterConversion.ToV128(right.v4_4)))); + return new uint8(RegisterConversion.ToUInt4(Xse.rem_epu32(RegisterConversion.ToV128(left.v4_0), RegisterConversion.ToV128(right.v4_0))), + RegisterConversion.ToUInt4(Xse.rem_epu32(RegisterConversion.ToV128(left.v4_4), RegisterConversion.ToV128(right.v4_4)))); } else { diff --git a/Runtime/Math Lib/Types/Vectors/long/long2.cs b/Runtime/Math Lib/Types/Vectors/long/long2.cs index f73c0a9..ae7fbd9 100644 --- a/Runtime/Math Lib/Types/Vectors/long/long2.cs +++ b/Runtime/Math Lib/Types/Vectors/long/long2.cs @@ -31,8 +31,6 @@ public DebuggerProxy(long2 v) } - [FieldOffset(0)] private fixed long asArray[2]; - [FieldOffset(0)] public long x; [FieldOffset(8)] public long y; @@ -587,10 +585,11 @@ public readonly long2 yy [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(long2 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(long2 input) => new v128 { SLong0 = input.x, SLong1 = input.y }; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator long2(v128 input) => RegisterConversion.ToType(input); + public static implicit operator long2(v128 input) => new long2 { x = input.SLong0, y = input.SLong1 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator long2(long input) => new long2(input); @@ -660,7 +659,7 @@ public static explicit operator uint2(long2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi64_epi32(input)); + return RegisterConversion.ToUInt2(Xse.cvtepi64_epi32(input)); } else { @@ -673,7 +672,7 @@ public static explicit operator int2(long2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi64_epi32(input)); + return RegisterConversion.ToInt2(Xse.cvtepi64_epi32(input)); } else { @@ -692,7 +691,7 @@ public static implicit operator double2(long2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi64_pd(input)); + return RegisterConversion.ToDouble2(Xse.cvtepi64_pd(input)); } return new double2((double)input.x, (double)input.y); @@ -706,7 +705,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 2); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return (long)Xse.extract_epi64(this, (byte)index); + } + else + { + long2 onStack = this; + + return *((long*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -714,7 +722,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 2); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi64(this, (ulong)value, (byte)index); + } + else + { + long2 onStack = this; + *((long*)&onStack + index) = value; + this = onStack; + } } } @@ -955,7 +972,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue64(Xse.cmpeq_epi64(left, right)); + int results = RegisterConversion.IsTrue64(Xse.cmpeq_epi64(left, right)); + + return *(bool2*)&results; } else { @@ -968,7 +987,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue64(Xse.cmplt_epi64(left, right)); + int results = RegisterConversion.IsTrue64(Xse.cmplt_epi64(left, right)); + + return *(bool2*)&results; } else { @@ -981,7 +1002,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue64(Xse.cmpgt_epi64(left, right)); + int results = RegisterConversion.IsTrue64(Xse.cmpgt_epi64(left, right)); + + return *(bool2*)&results; } else { @@ -995,7 +1018,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse64(Xse.cmpeq_epi64(left, right)); + int results = RegisterConversion.IsFalse64(Xse.cmpeq_epi64(left, right)); + + return *(bool2*)&results; } else { @@ -1008,7 +1033,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse64(Xse.cmpgt_epi64(left, right)); + int results = RegisterConversion.IsFalse64(Xse.cmpgt_epi64(left, right)); + + return *(bool2*)&results; } else { @@ -1021,7 +1048,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse64(Xse.cmplt_epi64(left, right)); + int results = RegisterConversion.IsFalse64(Xse.cmplt_epi64(left, right)); + + return *(bool2*)&results; } else { diff --git a/Runtime/Math Lib/Types/Vectors/long/long3.cs b/Runtime/Math Lib/Types/Vectors/long/long3.cs index df3eb24..c5b191c 100644 --- a/Runtime/Math Lib/Types/Vectors/long/long3.cs +++ b/Runtime/Math Lib/Types/Vectors/long/long3.cs @@ -33,8 +33,6 @@ public DebuggerProxy(long3 v) } - [FieldOffset(0)] private fixed long asArray[3]; - [FieldOffset(0)] internal long2 _xy; [FieldOffset(0)] public long x; @@ -2430,10 +2428,27 @@ public readonly long2 zz [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v256(long3 input) => RegisterConversion.ToV256(input); + public static implicit operator v256(long3 input) + { + if (Avx.IsAvxSupported) + { + v256 result = Avx.mm256_undefined_si256(); + + result.SLong0 = input.x; + result.SLong1 = input.y; + result.SLong2 = input.z; + + return result; + } + else + { + return new v256(input.x, input.y, input.z, 0); + } + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator long3(v256 input) => RegisterConversion.ToType(input); + public static implicit operator long3(v256 input) => new long3 { x = input.SLong0, y = input.SLong1, z = input.SLong2 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator long3(long input) => new long3(input); @@ -2523,19 +2538,19 @@ public static explicit operator uint3(long3 input) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi32(input)); + return RegisterConversion.ToUInt3(Xse.mm256_cvtepi64_epi32(input)); } else if (Sse4_1.IsSse41Supported) { v128 temp = Xse.cvtepi64_epi32(input._xy); - return RegisterConversion.ToType(Sse4_1.insert_epi32(temp, (int)input.z, 2)); + return RegisterConversion.ToUInt3(Sse4_1.insert_epi32(temp, (int)input.z, 2)); } else if (Sse2.IsSse2Supported) { v128 temp = Xse.cvtepi64_epi32(input._xy); - return RegisterConversion.ToType(Sse2.unpacklo_epi64(temp, Sse2.cvtsi32_si128((int)input.z))); + return RegisterConversion.ToUInt3(Sse2.unpacklo_epi64(temp, Sse2.cvtsi32_si128((int)input.z))); } else { @@ -2548,19 +2563,19 @@ public static explicit operator int3(long3 input) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi32(input)); + return RegisterConversion.ToInt3(Xse.mm256_cvtepi64_epi32(input)); } else if (Sse4_1.IsSse41Supported) { v128 temp = Xse.cvtepi64_epi32(input._xy); - return RegisterConversion.ToType(Sse4_1.insert_epi32(temp, (int)input.z, 2)); + return RegisterConversion.ToInt3(Sse4_1.insert_epi32(temp, (int)input.z, 2)); } else if (Sse2.IsSse2Supported) { v128 temp = Xse.cvtepi64_epi32(input._xy); - return RegisterConversion.ToType(Sse2.unpacklo_epi64(temp, Sse2.cvtsi32_si128((int)input.z))); + return RegisterConversion.ToInt3(Sse2.unpacklo_epi64(temp, Sse2.cvtsi32_si128((int)input.z))); } else { @@ -2579,7 +2594,7 @@ public static implicit operator double3(long3 input) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_cvtepi64_pd(input, 3)); + return RegisterConversion.ToDouble3(Xse.mm256_cvtepi64_pd(input, 3)); } else { @@ -2595,7 +2610,28 @@ readonly get { Assert.IsWithinArrayBounds(index, 3); - return asArray[index]; + if (Avx2.IsAvx2Supported) + { + return (long)Xse.mm256_extract_epi64(this, (byte)index); + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 2) + { + return (long)Xse.extract_epi64(_xy, (byte)index); + } + else + { + return z; + } + } + } + + long3 onStack = this; + + return *((long*)&onStack + index); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -2603,7 +2639,32 @@ readonly get { Assert.IsWithinArrayBounds(index, 3); - asArray[index] = value; + if (Avx2.IsAvx2Supported) + { + this = Xse.mm256_insert_epi64(this, (ulong)value, (byte)index); + + return; + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 2) + { + _xy = Xse.insert_epi64(_xy, (ulong)value, (byte)index); + } + else + { + z = value; + } + + return; + } + } + + long3 onStack = this; + *((long*)&onStack + index) = value; + this = onStack; } } @@ -2836,7 +2897,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return Xse.mm256_srai_epi64(x, n, 3); + return Xse.mm256_srai_epi64(x, n); } else { @@ -2850,7 +2911,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsTrue64(Avx2.mm256_cmpeq_epi64(left, right)); + int results = RegisterConversion.IsTrue64(Avx2.mm256_cmpeq_epi64(left, right)); + + return *(bool3*)&results; } else { @@ -2863,7 +2926,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsTrue64(Xse.mm256_cmplt_epi64(left, right, 3)); + int results = RegisterConversion.IsTrue64(Xse.mm256_cmplt_epi64(left, right, 3)); + + return *(bool3*)&results; } else { @@ -2876,7 +2941,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsTrue64(Xse.mm256_cmpgt_epi64(left, right, 3)); + int results = RegisterConversion.IsTrue64(Xse.mm256_cmpgt_epi64(left, right, 3)); + + return *(bool3*)&results; } else { @@ -2890,7 +2957,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsFalse64(Avx2.mm256_cmpeq_epi64(left, right)); + int results = RegisterConversion.IsFalse64(Avx2.mm256_cmpeq_epi64(left, right)); + + return *(bool3*)&results; } else { @@ -2903,7 +2972,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsFalse64(Xse.mm256_cmpgt_epi64(left, right, 3)); + int results = RegisterConversion.IsFalse64(Xse.mm256_cmpgt_epi64(left, right, 3)); + + return *(bool3*)&results; } else { @@ -2916,7 +2987,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsFalse64(Xse.mm256_cmplt_epi64(left, right, 3)); + int results = RegisterConversion.IsFalse64(Xse.mm256_cmplt_epi64(left, right, 3)); + + return *(bool3*)&results; } else { diff --git a/Runtime/Math Lib/Types/Vectors/long/long4.cs b/Runtime/Math Lib/Types/Vectors/long/long4.cs index 1ddeaf9..f010831 100644 --- a/Runtime/Math Lib/Types/Vectors/long/long4.cs +++ b/Runtime/Math Lib/Types/Vectors/long/long4.cs @@ -9,7 +9,6 @@ using DevTools; using static Unity.Burst.Intrinsics.X86; -using static MaxMath.maxmath; namespace MaxMath { @@ -35,8 +34,6 @@ public DebuggerProxy(long4 v) } - [FieldOffset(0)] private fixed long asArray[4]; - [FieldOffset(0)] internal long2 _xy; [FieldOffset(16)] internal long2 _zw; @@ -6098,10 +6095,11 @@ public readonly long2 ww [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v256(long4 input) => RegisterConversion.ToV256(input); + public static implicit operator v256(long4 input) => new v256 { SLong0 = input.x, SLong1 = input.y, SLong2 = input.z, SLong3 = input.w }; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator long4(v256 input) => RegisterConversion.ToType(input); + public static implicit operator long4(v256 input) => new long4 { x = input.SLong0, y = input.SLong1, z = input.SLong2, w = input.SLong3 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator long4(long input) => new long4(input); @@ -6127,7 +6125,11 @@ public static explicit operator long4(ulong4 input) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator long4(uint4 input) { - if (Sse2.IsSse2Supported) + if (Avx2.IsAvx2Supported) + { + return Avx2.mm256_cvtepu32_epi64(RegisterConversion.ToV128(input)); + } + else if (Sse2.IsSse2Supported) { return Cast.UInt4ToLong4(RegisterConversion.ToV128(input)); } @@ -6140,7 +6142,11 @@ public static implicit operator long4(uint4 input) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator long4(int4 input) { - if (Sse2.IsSse2Supported) + if (Avx2.IsAvx2Supported) + { + return Avx2.mm256_cvtepi32_epi64(RegisterConversion.ToV128(input)); + } + else if (Sse2.IsSse2Supported) { return Cast.Int4ToLong4(RegisterConversion.ToV128(input)); } @@ -6175,7 +6181,7 @@ public static explicit operator uint4(long4 input) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi32(input)); + return RegisterConversion.ToUInt4(Xse.mm256_cvtepi64_epi32(input)); } else { @@ -6188,7 +6194,7 @@ public static explicit operator int4(long4 input) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi32(input)); + return RegisterConversion.ToInt4(Xse.mm256_cvtepi64_epi32(input)); } else { @@ -6207,7 +6213,7 @@ public static implicit operator double4(long4 input) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_cvtepi64_pd(input, 4)); + return RegisterConversion.ToDouble4(Xse.mm256_cvtepi64_pd(input, 4)); } else { @@ -6223,7 +6229,28 @@ readonly get { Assert.IsWithinArrayBounds(index, 4); - return asArray[index]; + if (Avx2.IsAvx2Supported) + { + return (long)Xse.mm256_extract_epi64(this, (byte)index); + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 2) + { + return (long)Xse.extract_epi64(_xy, (byte)index); + } + else + { + return (long)Xse.extract_epi64(_zw, (byte)(index - 2)); + } + } + } + + long4 onStack = this; + + return *((long*)&onStack + index); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -6231,7 +6258,32 @@ readonly get { Assert.IsWithinArrayBounds(index, 4); - asArray[index] = value; + if (Avx2.IsAvx2Supported) + { + this = Xse.mm256_insert_epi64(this, (ulong)value, (byte)index); + + return; + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 2) + { + _xy = Xse.insert_epi64(_xy, (ulong)value, (byte)index); + } + else + { + _zw = Xse.insert_epi64(_zw, (ulong)value, (byte)(index - 2)); + } + + return; + } + } + + long4 onStack = this; + *((long*)&onStack + index) = value; + this = onStack; } } @@ -6465,7 +6517,7 @@ readonly get { if (Avx2.IsAvx2Supported) { - return Xse.mm256_srai_epi64(x, n, 4); + return Xse.mm256_srai_epi64(x, n); } else { @@ -6479,7 +6531,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsTrue64(Avx2.mm256_cmpeq_epi64(left, right)); + int results = RegisterConversion.IsTrue64(Avx2.mm256_cmpeq_epi64(left, right)); + + return *(bool4*)&results; } else { @@ -6492,7 +6546,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsTrue64(Xse.mm256_cmplt_epi64(left, right)); + int results = RegisterConversion.IsTrue64(Xse.mm256_cmplt_epi64(left, right)); + + return *(bool4*)&results; } else { @@ -6505,7 +6561,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsTrue64(Xse.mm256_cmpgt_epi64(left, right)); + int results = RegisterConversion.IsTrue64(Xse.mm256_cmpgt_epi64(left, right)); + + return *(bool4*)&results; } else { @@ -6519,7 +6577,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsFalse64(Avx2.mm256_cmpeq_epi64(left, right)); + int results = RegisterConversion.IsFalse64(Avx2.mm256_cmpeq_epi64(left, right)); + + return *(bool4*)&results; } else { @@ -6532,7 +6592,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsFalse64(Xse.mm256_cmpgt_epi64(left, right)); + int results = RegisterConversion.IsFalse64(Xse.mm256_cmpgt_epi64(left, right)); + + return *(bool4*)&results; } else { @@ -6545,7 +6607,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsFalse64(Xse.mm256_cmplt_epi64(left, right)); + int results = RegisterConversion.IsFalse64(Xse.mm256_cmplt_epi64(left, right)); + + return *(bool4*)&results; } else { diff --git a/Runtime/Math Lib/Types/Vectors/long/ulong2.cs b/Runtime/Math Lib/Types/Vectors/long/ulong2.cs index 46744ca..28b6a15 100644 --- a/Runtime/Math Lib/Types/Vectors/long/ulong2.cs +++ b/Runtime/Math Lib/Types/Vectors/long/ulong2.cs @@ -31,8 +31,6 @@ public DebuggerProxy(ulong2 v) } - [FieldOffset(0)] private fixed ulong asArray[2]; - [FieldOffset(0)] public ulong x; [FieldOffset(8)] public ulong y; @@ -587,10 +585,11 @@ public readonly ulong2 yy [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(ulong2 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(ulong2 input) => new v128 { ULong0 = input.x, ULong1 = input.y }; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator ulong2(v128 input) => RegisterConversion.ToType(input); + public static implicit operator ulong2(v128 input) => new ulong2 { x = input.ULong0, y = input.ULong1 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator ulong2(ulong input) => new ulong2(input); @@ -660,7 +659,7 @@ public static explicit operator uint2(ulong2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi64_epi32(input)); + return RegisterConversion.ToUInt2(Xse.cvtepi64_epi32(input)); } else { @@ -673,7 +672,7 @@ public static explicit operator int2(ulong2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi64_epi32(input)); + return RegisterConversion.ToInt2(Xse.cvtepi64_epi32(input)); } else { @@ -692,7 +691,7 @@ public static implicit operator double2(ulong2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu64_pd(input)); + return RegisterConversion.ToDouble2(Xse.cvtepu64_pd(input)); } return new double2((double)input.x, (double)input.y); @@ -706,7 +705,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 2); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return Xse.extract_epi64(this, (byte)index); + } + else + { + ulong2 onStack = this; + + return *((ulong*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -714,7 +722,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 2); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi64(this, value, (byte)index); + } + else + { + ulong2 onStack = this; + *((ulong*)&onStack + index) = value; + this = onStack; + } } } @@ -942,7 +959,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue64(Xse.cmpeq_epi64(left, right)); + int results = RegisterConversion.IsTrue64(Xse.cmpeq_epi64(left, right)); + + return *(bool2*)&results; } else { @@ -955,7 +974,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue64(Xse.cmplt_epu64(left, right)); + int results = RegisterConversion.IsTrue64(Xse.cmplt_epu64(left, right)); + + return *(bool2*)&results; } else { @@ -968,7 +989,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue64(Xse.cmpgt_epu64(left, right)); + int results = RegisterConversion.IsTrue64(Xse.cmpgt_epu64(left, right)); + + return *(bool2*)&results; } else { @@ -982,7 +1005,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse64(Xse.cmpeq_epi64(left, right)); + int results = RegisterConversion.IsFalse64(Xse.cmpeq_epi64(left, right)); + + return *(bool2*)&results; } else { @@ -995,7 +1020,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse64(Xse.cmpgt_epu64(left, right)); + int results = RegisterConversion.IsFalse64(Xse.cmpgt_epu64(left, right)); + + return *(bool2*)&results; } else { @@ -1008,7 +1035,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse64(Xse.cmplt_epu64(left, right)); + int results = RegisterConversion.IsFalse64(Xse.cmplt_epu64(left, right)); + + return *(bool2*)&results; } else { diff --git a/Runtime/Math Lib/Types/Vectors/long/ulong3.cs b/Runtime/Math Lib/Types/Vectors/long/ulong3.cs index fc54419..1014798 100644 --- a/Runtime/Math Lib/Types/Vectors/long/ulong3.cs +++ b/Runtime/Math Lib/Types/Vectors/long/ulong3.cs @@ -33,8 +33,6 @@ public DebuggerProxy(ulong3 v) } - [FieldOffset(0)] private fixed ulong asArray[3]; - [FieldOffset(0)] internal ulong2 _xy; [FieldOffset(0)] public ulong x; @@ -2430,10 +2428,27 @@ public readonly ulong2 zz [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v256(ulong3 input) => RegisterConversion.ToV256(input); + public static implicit operator v256(ulong3 input) + { + if (Avx.IsAvxSupported) + { + v256 result = Avx.mm256_undefined_si256(); + + result.ULong0 = input.x; + result.ULong1 = input.y; + result.ULong2 = input.z; + + return result; + } + else + { + return new v256(input.x, input.y, input.z, 0); + } + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator ulong3(v256 input) => RegisterConversion.ToType(input); + public static implicit operator ulong3(v256 input) => new ulong3 { x = input.ULong0, y = input.ULong1, z = input.ULong2 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator ulong3(ulong input) => new ulong3(input); @@ -2523,13 +2538,13 @@ public static explicit operator uint3(ulong3 input) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi32(input)); + return RegisterConversion.ToUInt3(Xse.mm256_cvtepi64_epi32(input)); } else if (Sse2.IsSse2Supported) { v128 temp = Xse.cvtepi64_epi32(input._xy); - return RegisterConversion.ToType(Sse2.unpacklo_epi64(temp, Sse2.cvtsi32_si128((int)input.z))); + return RegisterConversion.ToUInt3(Sse2.unpacklo_epi64(temp, Sse2.cvtsi32_si128((int)input.z))); } else { @@ -2542,13 +2557,13 @@ public static explicit operator int3(ulong3 input) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi32(input)); + return RegisterConversion.ToInt3(Xse.mm256_cvtepi64_epi32(input)); } else if (Sse2.IsSse2Supported) { v128 temp = Xse.cvtepi64_epi32(input._xy); - return RegisterConversion.ToType(Sse2.unpacklo_epi64(temp, Sse2.cvtsi32_si128((int)input.z))); + return RegisterConversion.ToInt3(Sse2.unpacklo_epi64(temp, Sse2.cvtsi32_si128((int)input.z))); } else { @@ -2567,7 +2582,7 @@ public static implicit operator double3(ulong3 input) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_cvtepu64_pd(input, 3)); + return RegisterConversion.ToDouble3(Xse.mm256_cvtepu64_pd(input, 3)); } else { @@ -2583,7 +2598,28 @@ readonly get { Assert.IsWithinArrayBounds(index, 3); - return asArray[index]; + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_extract_epi64(this, (byte)index); + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 2) + { + return Xse.extract_epi64(_xy, (byte)index); + } + else + { + return z; + } + } + } + + ulong3 onStack = this; + + return *((ulong*)&onStack + index); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -2591,7 +2627,32 @@ readonly get { Assert.IsWithinArrayBounds(index, 3); - asArray[index] = value; + if (Avx2.IsAvx2Supported) + { + this = Xse.mm256_insert_epi64(this, value, (byte)index); + + return; + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 2) + { + _xy = Xse.insert_epi64(_xy, value, (byte)index); + } + else + { + z = value; + } + + return; + } + } + + ulong3 onStack = this; + *((ulong*)&onStack + index) = value; + this = onStack; } } @@ -2826,7 +2887,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsTrue64(Avx2.mm256_cmpeq_epi64(left, right)); + int results = RegisterConversion.IsTrue64(Avx2.mm256_cmpeq_epi64(left, right)); + + return *(bool3*)&results; } else { @@ -2839,7 +2902,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsTrue64(Xse.mm256_cmplt_epu64(left, right)); + int results = RegisterConversion.IsTrue64(Xse.mm256_cmplt_epu64(left, right, 3)); + + return *(bool3*)&results; } else { @@ -2852,7 +2917,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsTrue64(Xse.mm256_cmpgt_epu64(left, right)); + int results = RegisterConversion.IsTrue64(Xse.mm256_cmpgt_epu64(left, right)); + + return *(bool3*)&results; } else { @@ -2866,7 +2933,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsFalse64(Avx2.mm256_cmpeq_epi64(left, right)); + int results = RegisterConversion.IsFalse64(Avx2.mm256_cmpeq_epi64(left, right)); + + return *(bool3*)&results; } else { @@ -2879,7 +2948,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsFalse64(Xse.mm256_cmpgt_epu64(left, right)); + int results = RegisterConversion.IsFalse64(Xse.mm256_cmpgt_epu64(left, right)); + + return *(bool3*)&results; } else { @@ -2892,7 +2963,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsFalse64(Xse.mm256_cmplt_epu64(left, right)); + int results = RegisterConversion.IsFalse64(Xse.mm256_cmplt_epu64(left, right, 3)); + + return *(bool3*)&results; } else { diff --git a/Runtime/Math Lib/Types/Vectors/long/ulong4.cs b/Runtime/Math Lib/Types/Vectors/long/ulong4.cs index 357cf09..728218e 100644 --- a/Runtime/Math Lib/Types/Vectors/long/ulong4.cs +++ b/Runtime/Math Lib/Types/Vectors/long/ulong4.cs @@ -9,7 +9,6 @@ using DevTools; using static Unity.Burst.Intrinsics.X86; -using static MaxMath.maxmath; namespace MaxMath { @@ -35,8 +34,6 @@ public DebuggerProxy(ulong4 v) } - [FieldOffset(0)] private fixed ulong asArray[4]; - [FieldOffset(0)] internal ulong2 _xy; [FieldOffset(16)] internal ulong2 _zw; @@ -6098,10 +6095,11 @@ public readonly ulong2 ww [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v256(ulong4 input) => RegisterConversion.ToV256(input); + public static implicit operator v256(ulong4 input) => new v256 { ULong0 = input.x, ULong1 = input.y, ULong2 = input.z, ULong3 = input.w }; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator ulong4(v256 input) => RegisterConversion.ToType(input); + public static implicit operator ulong4(v256 input) => new ulong4 { x = input.ULong0, y = input.ULong1, z = input.ULong2, w = input.ULong3 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator ulong4(ulong input) => new ulong4(input); @@ -6127,7 +6125,11 @@ public static explicit operator ulong4(long4 input) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator ulong4(uint4 input) { - if (Sse2.IsSse2Supported) + if (Avx2.IsAvx2Supported) + { + return Avx2.mm256_cvtepu32_epi64(RegisterConversion.ToV128(input)); + } + else if (Sse2.IsSse2Supported) { return (ulong4)Cast.UInt4ToLong4(RegisterConversion.ToV128(input)); } @@ -6140,7 +6142,11 @@ public static implicit operator ulong4(uint4 input) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator ulong4(int4 input) { - if (Sse2.IsSse2Supported) + if (Avx2.IsAvx2Supported) + { + return Avx2.mm256_cvtepi32_epi64(RegisterConversion.ToV128(input)); + } + else if (Sse2.IsSse2Supported) { return (ulong4)Cast.Int4ToLong4(RegisterConversion.ToV128(input)); } @@ -6175,7 +6181,7 @@ public static explicit operator uint4(ulong4 input) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi32(input)); + return RegisterConversion.ToUInt4(Xse.mm256_cvtepi64_epi32(input)); } else { @@ -6188,7 +6194,7 @@ public static explicit operator int4(ulong4 input) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_cvtepi64_epi32(input)); + return RegisterConversion.ToInt4(Xse.mm256_cvtepi64_epi32(input)); } else { @@ -6207,7 +6213,7 @@ public static implicit operator double4(ulong4 input) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(Xse.mm256_cvtepu64_pd(input, 4)); + return RegisterConversion.ToDouble4(Xse.mm256_cvtepu64_pd(input, 4)); } else { @@ -6223,7 +6229,28 @@ readonly get { Assert.IsWithinArrayBounds(index, 4); - return asArray[index]; + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_extract_epi64(this, (byte)index); + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 2) + { + return Xse.extract_epi64(_xy, (byte)index); + } + else + { + return Xse.extract_epi64(_zw, (byte)(index - 2)); + } + } + } + + ulong4 onStack = this; + + return *((ulong*)&onStack + index); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -6231,7 +6258,32 @@ readonly get { Assert.IsWithinArrayBounds(index, 4); - asArray[index] = value; + if (Avx2.IsAvx2Supported) + { + this = Xse.mm256_insert_epi64(this, value, (byte)index); + + return; + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 2) + { + _xy = Xse.insert_epi64(_xy, value, (byte)index); + } + else + { + _zw = Xse.insert_epi64(_zw, value, (byte)(index - 2)); + } + + return; + } + } + + ulong4 onStack = this; + *((ulong*)&onStack + index) = value; + this = onStack; } } @@ -6466,7 +6518,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsTrue64(Avx2.mm256_cmpeq_epi64(left, right)); + int results = RegisterConversion.IsTrue64(Avx2.mm256_cmpeq_epi64(left, right)); + + return *(bool4*)&results; } else { @@ -6479,7 +6533,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsTrue64(Xse.mm256_cmplt_epu64(left, right)); + int results = RegisterConversion.IsTrue64(Xse.mm256_cmplt_epu64(left, right)); + + return *(bool4*)&results; } else { @@ -6492,7 +6548,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsTrue64(Xse.mm256_cmpgt_epu64(left, right)); + int results = RegisterConversion.IsTrue64(Xse.mm256_cmpgt_epu64(left, right)); + + return *(bool4*)&results; } else { @@ -6506,7 +6564,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsFalse64(Avx2.mm256_cmpeq_epi64(left, right)); + int results = RegisterConversion.IsFalse64(Avx2.mm256_cmpeq_epi64(left, right)); + + return *(bool4*)&results; } else { @@ -6519,7 +6579,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsFalse64(Xse.mm256_cmpgt_epu64(left, right)); + int results = RegisterConversion.IsFalse64(Xse.mm256_cmpgt_epu64(left, right)); + + return *(bool4*)&results; } else { @@ -6532,7 +6594,9 @@ readonly get { if (Avx2.IsAvx2Supported) { - return RegisterConversion.IsFalse64(Xse.mm256_cmplt_epu64(left, right)); + int results = RegisterConversion.IsFalse64(Xse.mm256_cmplt_epu64(left, right)); + + return *(bool4*)&results; } else { diff --git a/Runtime/Math Lib/Types/Vectors/quarter/quarter2.cs b/Runtime/Math Lib/Types/Vectors/quarter/quarter2.cs index ebebbda..c9f782b 100644 --- a/Runtime/Math Lib/Types/Vectors/quarter/quarter2.cs +++ b/Runtime/Math Lib/Types/Vectors/quarter/quarter2.cs @@ -30,8 +30,6 @@ public DebuggerProxy(quarter2 v) } - [FieldOffset(0)] private fixed byte asArray[2]; - [FieldOffset(0)] public quarter x; [FieldOffset(1)] public quarter y; @@ -86,14 +84,41 @@ public quarter2(quarter xy) [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(quarter2 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(quarter2 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.Byte0 = input.x.value; + result.Byte1 = input.y.value; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator quarter2(v128 input) => RegisterConversion.ToType(input); + public static implicit operator quarter2(v128 input) => new quarter2 { x = maxmath.asquarter(input.Byte0), y = maxmath.asquarter(input.Byte1) }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator quarter2(quarter input) => new quarter2(input); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator quarter2(half input) => (quarter)input; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator quarter2(float input) => (quarter)input; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator quarter2(double input) => (quarter)input; + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static quarter2 SByte2ToQuarter2(sbyte2 input, quarter overflowValue) @@ -390,7 +415,7 @@ public static implicit operator float2(quarter2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.cvtpq_ps(input, elements: 2)); + return RegisterConversion.ToFloat2(quarter.Vectorized.cvtpq_ps(input, elements: 2)); } else { @@ -403,7 +428,7 @@ internal static float2 QuarterToFloatInRange(quarter2 q) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.cvtpq_ps(q, promiseInRange: true, elements: 2)); + return RegisterConversion.ToFloat2(quarter.Vectorized.cvtpq_ps(q, promiseInRange: true, elements: 2)); } else { @@ -416,7 +441,7 @@ internal static float2 QuarterToFloatInRangeAbs(quarter2 q) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.cvtpq_ps(q, promiseAbsoluteAndInRange: true, elements: 2)); + return RegisterConversion.ToFloat2(quarter.Vectorized.cvtpq_ps(q, promiseAbsoluteAndInRange: true, elements: 2)); } else { @@ -430,7 +455,7 @@ public static implicit operator double2(quarter2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.cvtpq_pd(input)); + return RegisterConversion.ToDouble2(quarter.Vectorized.cvtpq_pd(input)); } else { @@ -443,7 +468,7 @@ internal static double2 QuarterToDoubleInRange(quarter2 q) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.cvtpq_pd(q, promiseInRange: true)); + return RegisterConversion.ToDouble2(quarter.Vectorized.cvtpq_pd(q, promiseInRange: true)); } else { @@ -456,7 +481,7 @@ internal static double2 QuarterToDoubleInRangeAbs(quarter2 q) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.cvtpq_pd(q, promiseAbsoluteAndInRange: true)); + return RegisterConversion.ToDouble2(quarter.Vectorized.cvtpq_pd(q, promiseAbsoluteAndInRange: true)); } else { @@ -472,7 +497,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 2); - return asquarter(asArray[index]); + if (Sse2.IsSse2Supported) + { + return asquarter(Xse.extract_epi8(this, (byte)index)); + } + else + { + quarter2 onStack = this; + + return *((quarter*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -480,7 +514,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 2); - asArray[index] = asbyte(value); + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi8(this, asbyte(value), (byte)index); + } + else + { + quarter2 onStack = this; + *((quarter*)&onStack + index) = value; + this = onStack; + } } } @@ -497,7 +540,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(quarter.Vectorized.cmpeq_pq(left, right, 2)); + v128 results = RegisterConversion.IsTrue8(quarter.Vectorized.cmpeq_pq(left, right, elements: 2)); + + return *(bool2*)&results; } else { @@ -670,23 +715,15 @@ readonly get } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool2 operator != (quarter2 left, quarter2 right) { if (Sse2.IsSse2Supported) { - if (Xse.constexpr.IS_TRUE(left.x == 0f && left.y == 0f)) - { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(Sse2.and_si128(right, new byte2(0b0111_1111)), Sse2.setzero_si128())); - } - else if (Xse.constexpr.IS_TRUE(right.x == 0f && right.y == 0f)) - { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(Sse2.and_si128(left, new byte2(0b0111_1111)), Sse2.setzero_si128())); - } - else - { - return RegisterConversion.IsTrue8(quarter.Vectorized.cmpneq_pq(left, right, 2)); - } + v128 results = RegisterConversion.IsTrue8(quarter.Vectorized.cmpneq_pq(left, right, elements: 2)); + + return *(bool2*)&results; } else { @@ -859,13 +896,457 @@ readonly get } } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator < (quarter2 left, quarter2 right) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToBool2(RegisterConversion.IsTrue8(quarter.Vectorized.cmplt_pq(left, right, elements: 2))); + } + else + { + return new bool2(left.x < right.x, left.y < right.y); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator < (quarter2 left, quarter right) + { + return left < (quarter2)right; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator < (quarter left, quarter2 right) + { + return (quarter2)left < right; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator < (quarter2 left, half right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left < default(quarter2); + } + else + { + return (float2)left < (float2)right; + } + } + + public static bool2 operator < (half left, quarter2 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right > default(quarter2); + } + else + { + return (float2)left < (float2)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator < (quarter2 left, half2 right) + { + if (Xse.constexpr.IS_TRUE(math.all((float2)right == 0f))) + { + return left < default(quarter2); + } + else + { + return (float2)left < (float2)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator < (half2 left, quarter2 right) + { + if (Xse.constexpr.IS_TRUE(math.all((float2)left == 0f))) + { + return right > default(quarter2); + } + else + { + return (float2)left < (float2)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator < (quarter2 left, float right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left < default(quarter2); + } + else + { + return (float2)left < (float2)right; + } + } + + public static bool2 operator < (float left, quarter2 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right > default(quarter2); + } + else + { + return (float2)left < (float2)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator < (quarter2 left, float2 right) + { + if (Xse.constexpr.IS_TRUE(math.all(right == 0f))) + { + return left < default(quarter2); + } + else + { + return (float2)left < (float2)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator < (float2 left, quarter2 right) + { + if (Xse.constexpr.IS_TRUE(math.all(left == 0f))) + { + return right > default(quarter2); + } + else + { + return (float2)left < (float2)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator < (quarter2 left, double right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left < default(quarter2); + } + else + { + return (double2)left < (double2)right; + } + } + + public static bool2 operator < (double left, quarter2 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right > default(quarter2); + } + else + { + return (double2)left < (double2)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator < (quarter2 left, double2 right) + { + if (Xse.constexpr.IS_TRUE(math.all(right == 0f))) + { + return left < default(quarter2); + } + else + { + return (double2)left < (double2)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator < (double2 left, quarter2 right) + { + if (Xse.constexpr.IS_TRUE(math.all(left == 0f))) + { + return right > default(quarter2); + } + else + { + return (double2)left < (double2)right; + } + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator > (quarter2 left, quarter2 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator > (quarter2 left, quarter right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator > (quarter left, quarter2 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator > (quarter2 left, half right) => right < left; + + public static bool2 operator > (half left, quarter2 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator > (quarter2 left, half2 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator > (half2 left, quarter2 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator > (quarter2 left, float right) => right < left; + + public static bool2 operator > (float left, quarter2 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator > (quarter2 left, float2 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator > (float2 left, quarter2 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator > (quarter2 left, double right) => right < left; + + public static bool2 operator > (double left, quarter2 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator > (quarter2 left, double2 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator > (double2 left, quarter2 right) => right < left; + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator <= (quarter2 left, quarter2 right) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToBool2(RegisterConversion.IsTrue8(quarter.Vectorized.cmple_pq(left, right, elements: 2))); + } + else + { + return new bool2(left.x <= right.x, left.y <= right.y); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator <= (quarter2 left, quarter right) + { + return left <= (quarter2)right; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator <= (quarter left, quarter2 right) + { + return (quarter2)left <= right; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator <= (quarter2 left, half right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left <= default(quarter2); + } + else + { + return (float2)left <= (float2)right; + } + } + + public static bool2 operator <= (half left, quarter2 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right >= default(quarter2); + } + else + { + return (float2)left <= (float2)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator <= (quarter2 left, half2 right) + { + if (Xse.constexpr.IS_TRUE(math.all((float2)right == 0f))) + { + return left <= default(quarter2); + } + else + { + return (float2)left <= (float2)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator <= (half2 left, quarter2 right) + { + if (Xse.constexpr.IS_TRUE(math.all((float2)left == 0f))) + { + return right >= default(quarter2); + } + else + { + return (float2)left <= (float2)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator <= (quarter2 left, float right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left <= default(quarter2); + } + else + { + return (float2)left <= (float2)right; + } + } + + public static bool2 operator <= (float left, quarter2 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right >= default(quarter2); + } + else + { + return (float2)left <= (float2)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator <= (quarter2 left, float2 right) + { + if (Xse.constexpr.IS_TRUE(math.all(right == 0f))) + { + return left <= default(quarter2); + } + else + { + return (float2)left <= (float2)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator <= (float2 left, quarter2 right) + { + if (Xse.constexpr.IS_TRUE(math.all(left == 0f))) + { + return right >= default(quarter2); + } + else + { + return (float2)left <= (float2)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator <= (quarter2 left, double right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left <= default(quarter2); + } + else + { + return (double2)left <= (double2)right; + } + } + + public static bool2 operator <= (double left, quarter2 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right >= default(quarter2); + } + else + { + return (double2)left <= (double2)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator <= (quarter2 left, double2 right) + { + if (Xse.constexpr.IS_TRUE(math.all(right == 0f))) + { + return left <= default(quarter2); + } + else + { + return (double2)left <= (double2)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator <= (double2 left, quarter2 right) + { + if (Xse.constexpr.IS_TRUE(math.all(left == 0f))) + { + return right >= default(quarter2); + } + else + { + return (double2)left <= (double2)right; + } + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator >= (quarter2 left, quarter2 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator >= (quarter2 left, quarter right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator >= (quarter left, quarter2 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator >= (quarter2 left, half right) => right <= left; + + public static bool2 operator >= (half left, quarter2 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator >= (quarter2 left, half2 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator >= (half2 left, quarter2 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator >= (quarter2 left, float right) => right <= left; + + public static bool2 operator >= (float left, quarter2 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator >= (quarter2 left, float2 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator >= (float2 left, quarter2 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator >= (quarter2 left, double right) => right <= left; + + public static bool2 operator >= (double left, quarter2 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator >= (quarter2 left, double2 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool2 operator >= (double2 left, quarter2 right) => right <= left; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly bool Equals(quarter2 other) { if (Sse2.IsSse2Supported) { - return quarter.Vectorized.vcmpeq_pq(this, other, 2); + return quarter.Vectorized.vcmpeq_pq(this, other, elements: 2); } else { diff --git a/Runtime/Math Lib/Types/Vectors/quarter/quarter3.cs b/Runtime/Math Lib/Types/Vectors/quarter/quarter3.cs index 36f2d7b..999978c 100644 --- a/Runtime/Math Lib/Types/Vectors/quarter/quarter3.cs +++ b/Runtime/Math Lib/Types/Vectors/quarter/quarter3.cs @@ -32,8 +32,6 @@ public DebuggerProxy(quarter3 v) } - [FieldOffset(0)] private fixed byte asArray[3]; - [FieldOffset(0)] public quarter x; [FieldOffset(1)] public quarter y; [FieldOffset(2)] public quarter z; @@ -190,14 +188,42 @@ public quarter3(quarter x, quarter2 yz) [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(quarter3 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(quarter3 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.Byte0 = input.x.value; + result.Byte1 = input.y.value; + result.Byte2 = input.z.value; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator quarter3(v128 input) => RegisterConversion.ToType(input); + public static implicit operator quarter3(v128 input) => new quarter3 { x = maxmath.asquarter(input.Byte0), y = maxmath.asquarter(input.Byte1), z = maxmath.asquarter(input.Byte2) }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator quarter3(quarter input) => new quarter3(input); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator quarter3(half input) => (quarter)input; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator quarter3(float input) => (quarter)input; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator quarter3(double input) => (quarter)input; + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static quarter3 SByte3ToQuarter3(sbyte3 input, quarter overflowValue) @@ -499,7 +525,7 @@ public static implicit operator float3(quarter3 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.cvtpq_ps(input, elements: 3)); + return RegisterConversion.ToFloat3(quarter.Vectorized.cvtpq_ps(input, elements: 3)); } else { @@ -512,7 +538,7 @@ internal static float3 QuarterToFloatInRange(quarter3 q) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.cvtpq_ps(q, promiseInRange: true, elements: 3)); + return RegisterConversion.ToFloat3(quarter.Vectorized.cvtpq_ps(q, promiseInRange: true, elements: 3)); } else { @@ -525,7 +551,7 @@ internal static float3 QuarterToFloatInRangeAbs(quarter3 q) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.cvtpq_ps(q, promiseAbsoluteAndInRange: true, elements: 3)); + return RegisterConversion.ToFloat3(quarter.Vectorized.cvtpq_ps(q, promiseAbsoluteAndInRange: true, elements: 3)); } else { @@ -539,7 +565,7 @@ public static implicit operator double3(quarter3 input) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.mm256_cvtpq_pd(input, elements: 3)); + return RegisterConversion.ToDouble3(quarter.Vectorized.mm256_cvtpq_pd(input, elements: 3)); } else { @@ -552,7 +578,7 @@ internal static double3 QuarterToDoubleInRange(quarter3 q) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.mm256_cvtpq_pd(q, promiseInRange: true, elements: 3)); + return RegisterConversion.ToDouble3(quarter.Vectorized.mm256_cvtpq_pd(q, promiseInRange: true, elements: 3)); } else { @@ -565,7 +591,7 @@ internal static double3 QuarterToDoubleInRangeAbs(quarter3 q) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.mm256_cvtpq_pd(q, promiseAbsoluteAndInRange: true, elements: 3)); + return RegisterConversion.ToDouble3(quarter.Vectorized.mm256_cvtpq_pd(q, promiseAbsoluteAndInRange: true, elements: 3)); } else { @@ -581,7 +607,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 3); - return asquarter(asArray[index]); + if (Sse2.IsSse2Supported) + { + return asquarter(Xse.extract_epi8(this, (byte)index)); + } + else + { + quarter3 onStack = this; + + return *((quarter*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -589,7 +624,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 3); - asArray[index] = asbyte(value); + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi8(this, asbyte(value), (byte)index); + } + else + { + quarter3 onStack = this; + *((quarter*)&onStack + index) = value; + this = onStack; + } } } @@ -606,7 +650,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(quarter.Vectorized.cmpeq_pq(left, right, 3)); + v128 results = RegisterConversion.IsTrue8(quarter.Vectorized.cmpeq_pq(left, right, elements: 3)); + + return *(bool3*)&results; } else { @@ -784,18 +830,9 @@ readonly get { if (Sse2.IsSse2Supported) { - if (Xse.constexpr.IS_TRUE(left.x == 0f && left.y == 0f && left.z == 0f)) - { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(Sse2.and_si128(right, new byte3(0b0111_1111)), Sse2.setzero_si128())); - } - else if (Xse.constexpr.IS_TRUE(right.x == 0f && right.y == 0f && right.z == 0f)) - { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(Sse2.and_si128(left, new byte3(0b0111_1111)), Sse2.setzero_si128())); - } - else - { - return RegisterConversion.IsTrue8(quarter.Vectorized.cmpneq_pq(left, right, 2)); - } + v128 results = RegisterConversion.IsTrue8(quarter.Vectorized.cmpneq_pq(left, right, elements: 2)); + + return *(bool3*)&results; } else { @@ -967,13 +1004,458 @@ readonly get return (double3)left != (double3)right; } } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator < (quarter3 left, quarter3 right) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToBool3(RegisterConversion.IsTrue8(quarter.Vectorized.cmplt_pq(left, right, elements: 3))); + } + else + { + return new bool3(left.x < right.x, left.y < right.y, left.z < right.z); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator < (quarter3 left, quarter right) + { + return left < (quarter3)right; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator < (quarter left, quarter3 right) + { + return (quarter3)left < right; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator < (quarter3 left, half right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left < default(quarter3); + } + else + { + return (float3)left < (float3)right; + } + } + + public static bool3 operator < (half left, quarter3 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right > default(quarter3); + } + else + { + return (float3)left < (float3)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator < (quarter3 left, half3 right) + { + if (Xse.constexpr.IS_TRUE(math.all((float3)right == 0f))) + { + return left < default(quarter3); + } + else + { + return (float3)left < (float3)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator < (half3 left, quarter3 right) + { + if (Xse.constexpr.IS_TRUE(math.all((float3)left == 0f))) + { + return right > default(quarter3); + } + else + { + return (float3)left < (float3)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator < (quarter3 left, float right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left < default(quarter3); + } + else + { + return (float3)left < (float3)right; + } + } + + public static bool3 operator < (float left, quarter3 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right > default(quarter3); + } + else + { + return (float3)left < (float3)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator < (quarter3 left, float3 right) + { + if (Xse.constexpr.IS_TRUE(math.all(right == 0f))) + { + return left < default(quarter3); + } + else + { + return (float3)left < (float3)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator < (float3 left, quarter3 right) + { + if (Xse.constexpr.IS_TRUE(math.all(left == 0f))) + { + return right > default(quarter3); + } + else + { + return (float3)left < (float3)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator < (quarter3 left, double right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left < default(quarter3); + } + else + { + return (double3)left < (double3)right; + } + } + + public static bool3 operator < (double left, quarter3 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right > default(quarter3); + } + else + { + return (double3)left < (double3)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator < (quarter3 left, double3 right) + { + if (Xse.constexpr.IS_TRUE(math.all(right == 0f))) + { + return left < default(quarter3); + } + else + { + return (double3)left < (double3)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator < (double3 left, quarter3 right) + { + if (Xse.constexpr.IS_TRUE(math.all(left == 0f))) + { + return right > default(quarter3); + } + else + { + return (double3)left < (double3)right; + } + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator > (quarter3 left, quarter3 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator > (quarter3 left, quarter right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator > (quarter left, quarter3 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator > (quarter3 left, half right) => right < left; + + public static bool3 operator > (half left, quarter3 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator > (quarter3 left, half3 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator > (half3 left, quarter3 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator > (quarter3 left, float right) => right < left; + + public static bool3 operator > (float left, quarter3 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator > (quarter3 left, float3 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator > (float3 left, quarter3 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator > (quarter3 left, double right) => right < left; + + public static bool3 operator > (double left, quarter3 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator > (quarter3 left, double3 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator > (double3 left, quarter3 right) => right < left; + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator <= (quarter3 left, quarter3 right) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToBool3(RegisterConversion.IsTrue8(quarter.Vectorized.cmple_pq(left, right, elements: 3))); + } + else + { + return new bool3(left.x <= right.x, left.y <= right.y, left.z <= right.z); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator <= (quarter3 left, quarter right) + { + return left <= (quarter3)right; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator <= (quarter left, quarter3 right) + { + return (quarter3)left <= right; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator <= (quarter3 left, half right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left <= default(quarter3); + } + else + { + return (float3)left <= (float3)right; + } + } + + public static bool3 operator <= (half left, quarter3 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right >= default(quarter3); + } + else + { + return (float3)left <= (float3)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator <= (quarter3 left, half3 right) + { + if (Xse.constexpr.IS_TRUE(math.all((float3)right == 0f))) + { + return left <= default(quarter3); + } + else + { + return (float3)left <= (float3)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator <= (half3 left, quarter3 right) + { + if (Xse.constexpr.IS_TRUE(math.all((float3)left == 0f))) + { + return right >= default(quarter3); + } + else + { + return (float3)left <= (float3)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator <= (quarter3 left, float right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left <= default(quarter3); + } + else + { + return (float3)left <= (float3)right; + } + } + + public static bool3 operator <= (float left, quarter3 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right >= default(quarter3); + } + else + { + return (float3)left <= (float3)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator <= (quarter3 left, float3 right) + { + if (Xse.constexpr.IS_TRUE(math.all(right == 0f))) + { + return left <= default(quarter3); + } + else + { + return (float3)left <= (float3)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator <= (float3 left, quarter3 right) + { + if (Xse.constexpr.IS_TRUE(math.all(left == 0f))) + { + return right >= default(quarter3); + } + else + { + return (float3)left <= (float3)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator <= (quarter3 left, double right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left <= default(quarter3); + } + else + { + return (double3)left <= (double3)right; + } + } + + public static bool3 operator <= (double left, quarter3 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right >= default(quarter3); + } + else + { + return (double3)left <= (double3)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator <= (quarter3 left, double3 right) + { + if (Xse.constexpr.IS_TRUE(math.all(right == 0f))) + { + return left <= default(quarter3); + } + else + { + return (double3)left <= (double3)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator <= (double3 left, quarter3 right) + { + if (Xse.constexpr.IS_TRUE(math.all(left == 0f))) + { + return right >= default(quarter3); + } + else + { + return (double3)left <= (double3)right; + } + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator >= (quarter3 left, quarter3 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator >= (quarter3 left, quarter right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator >= (quarter left, quarter3 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator >= (quarter3 left, half right) => right <= left; + + public static bool3 operator >= (half left, quarter3 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator >= (quarter3 left, half3 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator >= (half3 left, quarter3 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator >= (quarter3 left, float right) => right <= left; + + public static bool3 operator >= (float left, quarter3 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator >= (quarter3 left, float3 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator >= (float3 left, quarter3 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator >= (quarter3 left, double right) => right <= left; + + public static bool3 operator >= (double left, quarter3 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator >= (quarter3 left, double3 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool3 operator >= (double3 left, quarter3 right) => right <= left; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly bool Equals(quarter3 other) { if (Sse2.IsSse2Supported) { - return quarter.Vectorized.vcmpeq_pq(this, other, 3); + return quarter.Vectorized.vcmpeq_pq(this, other, elements: 3); } else { @@ -993,7 +1475,7 @@ public override readonly int GetHashCode() } else { - return asArray[0] | (asArray[1] << 8) | (asArray[2] << 16); + return asbyte(x) | (asbyte(y) << 8) | (asbyte(z) << 16); } } diff --git a/Runtime/Math Lib/Types/Vectors/quarter/quarter4.cs b/Runtime/Math Lib/Types/Vectors/quarter/quarter4.cs index 28637c5..40dc581 100644 --- a/Runtime/Math Lib/Types/Vectors/quarter/quarter4.cs +++ b/Runtime/Math Lib/Types/Vectors/quarter/quarter4.cs @@ -34,8 +34,6 @@ public DebuggerProxy(quarter4 v) } - [FieldOffset(0)] private fixed byte asArray[4]; - [FieldOffset(0)] public quarter x; [FieldOffset(1)] public quarter y; [FieldOffset(2)] public quarter z; @@ -435,14 +433,43 @@ public quarter4(quarter x, quarter3 yzw) [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(quarter4 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(quarter4 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.Byte0 = input.x.value; + result.Byte1 = input.y.value; + result.Byte2 = input.z.value; + result.Byte3 = input.w.value; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator quarter4(v128 input) => RegisterConversion.ToType(input); + public static implicit operator quarter4(v128 input) => new quarter4 { x = maxmath.asquarter(input.Byte0), y = maxmath.asquarter(input.Byte1), z = maxmath.asquarter(input.Byte2), w = maxmath.asquarter(input.Byte3) }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator quarter4(quarter input) => new quarter4(input); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator quarter4(half input) => (quarter)input; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator quarter4(float input) => (quarter)input; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator quarter4(double input) => (quarter)input; + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static quarter4 SByte4ToQuarter4(sbyte4 input, quarter overflowValue) @@ -750,7 +777,7 @@ public static implicit operator float4(quarter4 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.cvtpq_ps(input, elements: 4)); + return RegisterConversion.ToFloat4(quarter.Vectorized.cvtpq_ps(input, elements: 4)); } else { @@ -763,7 +790,7 @@ internal static float4 QuarterToFloatInRange(quarter4 q) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.cvtpq_ps(q, promiseInRange: true, elements: 4)); + return RegisterConversion.ToFloat4(quarter.Vectorized.cvtpq_ps(q, promiseInRange: true, elements: 4)); } else { @@ -776,7 +803,7 @@ internal static float4 QuarterToFloatInRangeAbs(quarter4 q) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.cvtpq_ps(q, promiseAbsoluteAndInRange: true, elements: 4)); + return RegisterConversion.ToFloat4(quarter.Vectorized.cvtpq_ps(q, promiseAbsoluteAndInRange: true, elements: 4)); } else { @@ -790,7 +817,7 @@ public static implicit operator double4(quarter4 input) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.mm256_cvtpq_pd(input, elements: 4)); + return RegisterConversion.ToDouble4(quarter.Vectorized.mm256_cvtpq_pd(input, elements: 4)); } else { @@ -803,7 +830,7 @@ internal static double4 QuarterToDoubleInRange(quarter4 q) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.mm256_cvtpq_pd(q, promiseInRange: true, elements: 4)); + return RegisterConversion.ToDouble4(quarter.Vectorized.mm256_cvtpq_pd(q, promiseInRange: true, elements: 4)); } else { @@ -816,7 +843,7 @@ internal static double4 QuarterToDoubleInRangeAbs(quarter4 q) { if (Avx2.IsAvx2Supported) { - return RegisterConversion.ToType(quarter.Vectorized.mm256_cvtpq_pd(q, promiseAbsoluteAndInRange: true, elements: 4)); + return RegisterConversion.ToDouble4(quarter.Vectorized.mm256_cvtpq_pd(q, promiseAbsoluteAndInRange: true, elements: 4)); } else { @@ -832,7 +859,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 4); - return asquarter(asArray[index]); + if (Sse2.IsSse2Supported) + { + return asquarter(Xse.extract_epi8(this, (byte)index)); + } + else + { + quarter4 onStack = this; + + return *((quarter*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -840,7 +876,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 4); - asArray[index] = asbyte(value); + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi8(this, asbyte(value), (byte)index); + } + else + { + quarter4 onStack = this; + *((quarter*)&onStack + index) = value; + this = onStack; + } } } @@ -857,7 +902,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(quarter.Vectorized.cmpeq_pq(left, right, 4)); + v128 results = RegisterConversion.IsTrue8(quarter.Vectorized.cmpeq_pq(left, right, elements: 4)); + + return *(bool4*)&results; } else { @@ -1035,18 +1082,9 @@ readonly get { if (Sse2.IsSse2Supported) { - if (Xse.constexpr.IS_TRUE(left.x == 0f && left.y == 0f && left.z == 0f && left.w == 0f)) - { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(Sse2.and_si128(right, new byte4(0b0111_1111)), Sse2.setzero_si128())); - } - else if (Xse.constexpr.IS_TRUE(right.x == 0f && right.y == 0f && right.z == 0f && right.w == 0f)) - { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(Sse2.and_si128(left, new byte4(0b0111_1111)), Sse2.setzero_si128())); - } - else - { - return RegisterConversion.IsTrue8(quarter.Vectorized.cmpneq_pq(left, right, 4)); - } + v128 results = RegisterConversion.IsTrue8(quarter.Vectorized.cmpneq_pq(left, right, elements: 4)); + + return *(bool4*)&results; } else { @@ -1219,12 +1257,457 @@ readonly get } } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator < (quarter4 left, quarter4 right) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToBool4(RegisterConversion.IsTrue8(quarter.Vectorized.cmplt_pq(left, right, elements: 4))); + } + else + { + return new bool4(left.x < right.x, left.y < right.y, left.z < right.z, left.w < right.w); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator < (quarter4 left, quarter right) + { + return left < (quarter4)right; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator < (quarter left, quarter4 right) + { + return (quarter4)left < right; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator < (quarter4 left, half right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left < default(quarter4); + } + else + { + return (float4)left < (float4)right; + } + } + + public static bool4 operator < (half left, quarter4 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right > default(quarter4); + } + else + { + return (float4)left < (float4)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator < (quarter4 left, half4 right) + { + if (Xse.constexpr.IS_TRUE(math.all((float4)right == 0f))) + { + return left < default(quarter4); + } + else + { + return (float4)left < (float4)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator < (half4 left, quarter4 right) + { + if (Xse.constexpr.IS_TRUE(math.all((float4)left == 0f))) + { + return right > default(quarter4); + } + else + { + return (float4)left < (float4)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator < (quarter4 left, float right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left < default(quarter4); + } + else + { + return (float4)left < (float4)right; + } + } + + public static bool4 operator < (float left, quarter4 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right > default(quarter4); + } + else + { + return (float4)left < (float4)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator < (quarter4 left, float4 right) + { + if (Xse.constexpr.IS_TRUE(math.all(right == 0f))) + { + return left < default(quarter4); + } + else + { + return (float4)left < (float4)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator < (float4 left, quarter4 right) + { + if (Xse.constexpr.IS_TRUE(math.all(left == 0f))) + { + return right > default(quarter4); + } + else + { + return (float4)left < (float4)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator < (quarter4 left, double right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left < default(quarter4); + } + else + { + return (double4)left < (double4)right; + } + } + + public static bool4 operator < (double left, quarter4 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right > default(quarter4); + } + else + { + return (double4)left < (double4)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator < (quarter4 left, double4 right) + { + if (Xse.constexpr.IS_TRUE(math.all(right == 0f))) + { + return left < default(quarter4); + } + else + { + return (double4)left < (double4)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator < (double4 left, quarter4 right) + { + if (Xse.constexpr.IS_TRUE(math.all(left == 0f))) + { + return right > default(quarter4); + } + else + { + return (double4)left < (double4)right; + } + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator > (quarter4 left, quarter4 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator > (quarter4 left, quarter right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator > (quarter left, quarter4 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator > (quarter4 left, half right) => right < left; + + public static bool4 operator > (half left, quarter4 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator > (quarter4 left, half4 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator > (half4 left, quarter4 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator > (quarter4 left, float right) => right < left; + + public static bool4 operator > (float left, quarter4 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator > (quarter4 left, float4 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator > (float4 left, quarter4 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator > (quarter4 left, double right) => right < left; + + public static bool4 operator > (double left, quarter4 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator > (quarter4 left, double4 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator > (double4 left, quarter4 right) => right < left; + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator <= (quarter4 left, quarter4 right) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.ToBool4(RegisterConversion.IsTrue8(quarter.Vectorized.cmple_pq(left, right, elements: 4))); + } + else + { + return new bool4(left.x <= right.x, left.y <= right.y, left.z <= right.z, left.w <= right.w); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator <= (quarter4 left, quarter right) + { + return left <= (quarter4)right; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator <= (quarter left, quarter4 right) + { + return (quarter4)left <= right; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator <= (quarter4 left, half right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left <= default(quarter4); + } + else + { + return (float4)left <= (float4)right; + } + } + + public static bool4 operator <= (half left, quarter4 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right >= default(quarter4); + } + else + { + return (float4)left <= (float4)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator <= (quarter4 left, half4 right) + { + if (Xse.constexpr.IS_TRUE(math.all((float4)right == 0f))) + { + return left <= default(quarter4); + } + else + { + return (float4)left <= (float4)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator <= (half4 left, quarter4 right) + { + if (Xse.constexpr.IS_TRUE(math.all((float4)left == 0f))) + { + return right >= default(quarter4); + } + else + { + return (float4)left <= (float4)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator <= (quarter4 left, float right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left <= default(quarter4); + } + else + { + return (float4)left <= (float4)right; + } + } + + public static bool4 operator <= (float left, quarter4 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right >= default(quarter4); + } + else + { + return (float4)left <= (float4)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator <= (quarter4 left, float4 right) + { + if (Xse.constexpr.IS_TRUE(math.all(right == 0f))) + { + return left <= default(quarter4); + } + else + { + return (float4)left <= (float4)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator <= (float4 left, quarter4 right) + { + if (Xse.constexpr.IS_TRUE(math.all(left == 0f))) + { + return right >= default(quarter4); + } + else + { + return (float4)left <= (float4)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator <= (quarter4 left, double right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left <= default(quarter4); + } + else + { + return (double4)left <= (double4)right; + } + } + + public static bool4 operator <= (double left, quarter4 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right >= default(quarter4); + } + else + { + return (double4)left <= (double4)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator <= (quarter4 left, double4 right) + { + if (Xse.constexpr.IS_TRUE(math.all(right == 0f))) + { + return left <= default(quarter4); + } + else + { + return (double4)left <= (double4)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator <= (double4 left, quarter4 right) + { + if (Xse.constexpr.IS_TRUE(math.all(left == 0f))) + { + return right >= default(quarter4); + } + else + { + return (double4)left <= (double4)right; + } + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator >= (quarter4 left, quarter4 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator >= (quarter4 left, quarter right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator >= (quarter left, quarter4 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator >= (quarter4 left, half right) => right <= left; + + public static bool4 operator >= (half left, quarter4 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator >= (quarter4 left, half4 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator >= (half4 left, quarter4 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator >= (quarter4 left, float right) => right <= left; + + public static bool4 operator >= (float left, quarter4 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator >= (quarter4 left, float4 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator >= (float4 left, quarter4 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator >= (quarter4 left, double right) => right <= left; + + public static bool4 operator >= (double left, quarter4 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator >= (quarter4 left, double4 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool4 operator >= (double4 left, quarter4 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly bool Equals(quarter4 other) { if (Sse2.IsSse2Supported) { - return quarter.Vectorized.vcmpeq_pq(this, other, 4); + return quarter.Vectorized.vcmpeq_pq(this, other, elements: 4); } else { diff --git a/Runtime/Math Lib/Types/Vectors/quarter/quarter8.cs b/Runtime/Math Lib/Types/Vectors/quarter/quarter8.cs index 4d438bc..e0fa265 100644 --- a/Runtime/Math Lib/Types/Vectors/quarter/quarter8.cs +++ b/Runtime/Math Lib/Types/Vectors/quarter/quarter8.cs @@ -43,8 +43,6 @@ public DebuggerProxy(quarter8 v) } - [FieldOffset(0)] private fixed byte asArray[8]; - [FieldOffset(0)] public quarter x0; [FieldOffset(1)] public quarter x1; [FieldOffset(2)] public quarter x2; @@ -142,14 +140,47 @@ public quarter8(quarter4 x0123, quarter4 x4567) [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(quarter8 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(quarter8 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.Byte0 = input.x0.value; + result.Byte1 = input.x1.value; + result.Byte2 = input.x2.value; + result.Byte3 = input.x3.value; + result.Byte4 = input.x4.value; + result.Byte5 = input.x5.value; + result.Byte6 = input.x6.value; + result.Byte7 = input.x7.value; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator quarter8(v128 input) => RegisterConversion.ToType(input); + public static implicit operator quarter8(v128 input) => new quarter8 { x0 = maxmath.asquarter(input.Byte0), x1 = maxmath.asquarter(input.Byte1), x2 = maxmath.asquarter(input.Byte2), x3 = maxmath.asquarter(input.Byte3), x4 = maxmath.asquarter(input.Byte4), x5 = maxmath.asquarter(input.Byte5), x6 = maxmath.asquarter(input.Byte6), x7 = maxmath.asquarter(input.Byte7) }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator quarter8(quarter input) => new quarter8(input); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator quarter8(half input) => (quarter)input; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator quarter8(float input) => (quarter)input; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator quarter8(double input) => (quarter)input; + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static quarter8 Byte8ToQuarter8(byte8 input, quarter overflowValue) @@ -420,11 +451,20 @@ internal static float8 QuarterToFloatInRangeAbs(quarter8 q) public quarter this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get + readonly get { Assert.IsWithinArrayBounds(index, 8); - return asquarter(asArray[index]); + if (Sse2.IsSse2Supported) + { + return asquarter(Xse.extract_epi8(this, (byte)index)); + } + else + { + quarter8 onStack = this; + + return *((quarter*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -432,7 +472,16 @@ public quarter this[int index] { Assert.IsWithinArrayBounds(index, 8); - asArray[index] = asbyte(value); + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi8(this, asbyte(value), (byte)index); + } + else + { + quarter8 onStack = this; + *((quarter*)&onStack + index) = value; + this = onStack; + } } } @@ -449,7 +498,7 @@ public quarter this[int index] { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue8(quarter.Vectorized.cmpeq_pq(left, right, 8)); + return RegisterConversion.IsTrue8(quarter.Vectorized.cmpeq_pq(left, right, elements: 8)); } else { @@ -601,18 +650,7 @@ public quarter this[int index] { if (Sse2.IsSse2Supported) { - if (Xse.constexpr.IS_TRUE(left.x0 == 0f && left.x1 == 0f && left.x2 == 0f && left.x3 == 0f && left.x4 == 0f && left.x5 == 0f && left.x6 == 0f && left.x7 == 0f)) - { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(Sse2.and_si128(right, new byte8(0b0111_1111)), Sse2.setzero_si128())); - } - else if (Xse.constexpr.IS_TRUE(right.x0 == 0f && right.x1 == 0f && right.x2 == 0f && right.x3 == 0f && right.x4 == 0f && right.x5 == 0f && right.x6 == 0f && right.x7 == 0f)) - { - return RegisterConversion.IsFalse8(Sse2.cmpeq_epi8(Sse2.and_si128(left, new byte8(0b0111_1111)), Sse2.setzero_si128())); - } - else - { - return RegisterConversion.IsTrue8(quarter.Vectorized.cmpneq_pq(left, right, 8)); - } + return RegisterConversion.IsTrue8(quarter.Vectorized.cmpneq_pq(left, right, elements: 8)); } else { @@ -760,12 +798,392 @@ public quarter this[int index] } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator < (quarter8 left, quarter8 right) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.IsTrue8(quarter.Vectorized.cmplt_pq(left, right, elements: 8)); + } + else + { + return new bool8(left.x0 < right.x0, left.x1 < right.x1, left.x2 < right.x2, left.x3 < right.x3, left.x4 < right.x4, left.x5 < right.x5, left.x6 < right.x6, left.x7 < right.x7); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator < (quarter8 left, quarter right) + { + return left < (quarter8)right; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator < (quarter left, quarter8 right) + { + return (quarter8)left < right; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator < (quarter8 left, half right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left < default(quarter8); + } + else + { + return (float8)left < (float8)right; + } + } + + public static bool8 operator < (half left, quarter8 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right > default(quarter8); + } + else + { + return (float8)left < (float8)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator < (quarter8 left, half8 right) + { + if (Xse.constexpr.IS_TRUE(maxmath.all((float8)right == 0f))) + { + return left < default(quarter8); + } + else + { + return (float8)left < (float8)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator < (half8 left, quarter8 right) + { + if (Xse.constexpr.IS_TRUE(maxmath.all((float8)left == 0f))) + { + return right > default(quarter8); + } + else + { + return (float8)left < (float8)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator < (quarter8 left, float right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left < default(quarter8); + } + else + { + return (float8)left < (float8)right; + } + } + + public static bool8 operator < (float left, quarter8 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right > default(quarter8); + } + else + { + return (float8)left < (float8)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator < (quarter8 left, float8 right) + { + if (Xse.constexpr.IS_TRUE(maxmath.all(right == 0f))) + { + return left < default(quarter8); + } + else + { + return (float8)left < (float8)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator < (float8 left, quarter8 right) + { + if (Xse.constexpr.IS_TRUE(maxmath.all(left == 0f))) + { + return right > default(quarter8); + } + else + { + return (float8)left < (float8)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator < (quarter8 left, double right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left < default(quarter8); + } + else + { + return new bool8((double4)left.v4_0 < (double4)right, (double4)left.v4_4 < (double4)right); + } + } + + public static bool8 operator < (double left, quarter8 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right > default(quarter8); + } + else + { + return new bool8((double4)left < (double4)right.v4_0, (double4)left < (double4)right.v4_4); + } + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator > (quarter8 left, quarter8 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator > (quarter8 left, quarter right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator > (quarter left, quarter8 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator > (quarter8 left, half right) => right < left; + + public static bool8 operator > (half left, quarter8 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator > (quarter8 left, half8 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator > (half8 left, quarter8 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator > (quarter8 left, float right) => right < left; + + public static bool8 operator > (float left, quarter8 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator > (quarter8 left, float8 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator > (float8 left, quarter8 right) => right < left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator > (quarter8 left, double right) => right < left; + + public static bool8 operator > (double left, quarter8 right) => right < left; + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator <= (quarter8 left, quarter8 right) + { + if (Sse2.IsSse2Supported) + { + return RegisterConversion.IsTrue8(quarter.Vectorized.cmple_pq(left, right, elements: 8)); + } + else + { + return new bool8(left.x0 <= right.x0, left.x1 <= right.x1, left.x2 <= right.x2, left.x3 <= right.x3, left.x4 <= right.x4, left.x5 <= right.x5, left.x6 <= right.x6, left.x7 <= right.x7); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator <= (quarter8 left, quarter right) + { + return left <= (quarter8)right; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator <= (quarter left, quarter8 right) + { + return (quarter8)left <= right; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator <= (quarter8 left, half right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left <= default(quarter8); + } + else + { + return (float8)left <= (float8)right; + } + } + + public static bool8 operator <= (half left, quarter8 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right >= default(quarter8); + } + else + { + return (float8)left <= (float8)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator <= (quarter8 left, half8 right) + { + if (Xse.constexpr.IS_TRUE(maxmath.all((float8)right == 0f))) + { + return left <= default(quarter8); + } + else + { + return (float8)left <= (float8)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator <= (half8 left, quarter8 right) + { + if (Xse.constexpr.IS_TRUE(maxmath.all((float8)left == 0f))) + { + return right >= default(quarter8); + } + else + { + return (float8)left <= (float8)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator <= (quarter8 left, float right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left <= default(quarter8); + } + else + { + return (float8)left <= (float8)right; + } + } + + public static bool8 operator <= (float left, quarter8 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right >= default(quarter8); + } + else + { + return (float8)left <= (float8)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator <= (quarter8 left, float8 right) + { + if (Xse.constexpr.IS_TRUE(maxmath.all(right == 0f))) + { + return left <= default(quarter8); + } + else + { + return (float8)left <= (float8)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator <= (float8 left, quarter8 right) + { + if (Xse.constexpr.IS_TRUE(maxmath.all(left == 0f))) + { + return right >= default(quarter8); + } + else + { + return (float8)left <= (float8)right; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator <= (quarter8 left, double right) + { + if (Xse.constexpr.IS_TRUE(right == 0f)) + { + return left <= default(quarter8); + } + else + { + return new bool8((double4)left.v4_0 <= (double4)right, (double4)left.v4_4 <= (double4)right); + } + } + + public static bool8 operator <= (double left, quarter8 right) + { + if (Xse.constexpr.IS_TRUE(left == 0f)) + { + return right >= default(quarter8); + } + else + { + return new bool8((double4)left <= (double4)right.v4_0, (double4)left <= (double4)right.v4_4); + } + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator >= (quarter8 left, quarter8 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator >= (quarter8 left, quarter right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator >= (quarter left, quarter8 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator >= (quarter8 left, half right) => right <= left; + + public static bool8 operator >= (half left, quarter8 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator >= (quarter8 left, half8 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator >= (half8 left, quarter8 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator >= (quarter8 left, float right) => right <= left; + + public static bool8 operator >= (float left, quarter8 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator >= (quarter8 left, float8 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator >= (float8 left, quarter8 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool8 operator >= (quarter8 left, double right) => right <= left; + + public static bool8 operator >= (double left, quarter8 right) => right <= left; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly bool Equals(quarter8 other) { if (Sse2.IsSse2Supported) { - return quarter.Vectorized.vcmpeq_pq(this, other, 8); + return quarter.Vectorized.vcmpeq_pq(this, other, elements: 8); } else { diff --git a/Runtime/Math Lib/Types/Vectors/short/short16.cs b/Runtime/Math Lib/Types/Vectors/short/short16.cs index 938e1a7..b7fa924 100644 --- a/Runtime/Math Lib/Types/Vectors/short/short16.cs +++ b/Runtime/Math Lib/Types/Vectors/short/short16.cs @@ -57,8 +57,6 @@ public DebuggerProxy(short16 v) } - [FieldOffset(0)] private fixed short asArray[16]; - [FieldOffset(0)] internal short8 _v8_0; [FieldOffset(16)] internal short8 _v8_8; @@ -136,7 +134,7 @@ public short16(short4 x0123, short3 x456, short3 x789, short3 x10_11_12, short3 if (Sse2.IsSse2Supported) { - lo = Sse2.insert_epi16(Sse2.unpacklo_epi64(x0123, x456), x789.x, 7); + lo = Xse.insert_epi16(Sse2.unpacklo_epi64(x0123, x456), (ushort)x789.x, 7); } else { @@ -2017,10 +2015,11 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v256(short16 input) => RegisterConversion.ToV256(input); + public static implicit operator v256(short16 input) => new v256{ SShort0 = input.x0, SShort1 = input.x1, SShort2 = input.x2, SShort3 = input.x3, SShort4 = input.x4, SShort5 = input.x5, SShort6 = input.x6, SShort7 = input.x7, SShort8 = input.x8, SShort9 = input.x9, SShort10 = input.x10, SShort11 = input.x11, SShort12 = input.x12, SShort13 = input.x13, SShort14 = input.x14, SShort15 = input.x15 }; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator short16(v256 input) => RegisterConversion.ToType(input); + public static implicit operator short16(v256 input) => new short16{ x0 = input.SShort0, x1 = input.SShort1, x2 = input.SShort2, x3 = input.SShort3, x4 = input.SShort4, x5 = input.SShort5, x6 = input.SShort6, x7 = input.SShort7, x8 = input.SShort8, x9 = input.SShort9, x10 = input.SShort10, x11 = input.SShort11, x12 = input.SShort12, x13 = input.SShort13, x14 = input.SShort14, x15 = input.SShort15 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator short16(short input) => new short16(input); @@ -2051,15 +2050,61 @@ readonly get { Assert.IsWithinArrayBounds(index, 16); - return asArray[index]; + if (Avx2.IsAvx2Supported) + { + return (short)Xse.mm256_extract_epi16(this, (byte)index); + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 8) + { + return (short)Xse.extract_epi16(_v8_0, (byte)index); + } + else + { + return (short)Xse.extract_epi16(_v8_8, (byte)(index - 8)); + } + } + } + + short16 onStack = this; + + return *((short*)&onStack + index); } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { Assert.IsWithinArrayBounds(index, 16); + + if (Avx2.IsAvx2Supported) + { + this = Xse.mm256_insert_epi16(this, (ushort)value, (byte)index); + + return; + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 8) + { + _v8_0 = Xse.insert_epi16(_v8_0, (ushort)value, (byte)index); + } + else + { + _v8_8 = Xse.insert_epi16(_v8_8, (ushort)value, (byte)(index - 8)); + } + + return; + } + } - asArray[index] = value; + short16 onStack = this; + *((short*)&onStack + index) = value; + this = onStack; } } diff --git a/Runtime/Math Lib/Types/Vectors/short/short2.cs b/Runtime/Math Lib/Types/Vectors/short/short2.cs index bd01687..bd18c07 100644 --- a/Runtime/Math Lib/Types/Vectors/short/short2.cs +++ b/Runtime/Math Lib/Types/Vectors/short/short2.cs @@ -31,8 +31,6 @@ public DebuggerProxy(short2 v) } - [FieldOffset(0)] private fixed short asArray[2]; - [FieldOffset(0)] public short x; [FieldOffset(2)] public short y; @@ -51,7 +49,7 @@ public short2(short x, short y) } else { - this = Sse2.insert_epi16(Sse2.cvtsi32_si128(x), y, 1); + this = Xse.insert_epi16(Sse2.cvtsi32_si128(x), (ushort)y, 1); } } else @@ -499,10 +497,28 @@ public readonly short2 yy [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(short2 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(short2 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.SShort0 = input.x; + result.SShort1 = input.y; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator short2(v128 input) => RegisterConversion.ToType(input); + public static implicit operator short2(v128 input) => new short2 { x = input.SShort0, y = input.SShort1 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator short2(short input) => new short2(input); @@ -588,7 +604,7 @@ public static implicit operator int2(short2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi16_epi32(input)); + return RegisterConversion.ToInt2(Xse.cvtepi16_epi32(input)); } else { @@ -601,7 +617,7 @@ public static explicit operator uint2(short2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi16_epi32(input)); + return RegisterConversion.ToUInt2(Xse.cvtepi16_epi32(input)); } else { @@ -643,7 +659,7 @@ public static implicit operator float2(short2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi16_ps(input)); + return RegisterConversion.ToFloat2(Xse.cvtepi16_ps(input)); } else { @@ -656,7 +672,7 @@ public static implicit operator double2(short2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi16_pd(input)); + return RegisterConversion.ToDouble2(Xse.cvtepi16_pd(input)); } else { @@ -672,7 +688,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 2); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return (short)Xse.extract_epi16(this, (byte)index); + } + else + { + short2 onStack = this; + + return *((short*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -680,7 +705,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 2); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi16(this, (ushort)value, (byte)index); + } + else + { + short2 onStack = this; + *((short*)&onStack + index) = value; + this = onStack; + } } } @@ -922,7 +956,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); + v128 results = RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); + + return *(bool2*)&results; } else { @@ -935,7 +971,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmplt_epi16(left, right)); + v128 results = RegisterConversion.IsTrue16(Xse.cmplt_epi16(left, right)); + + return *(bool2*)&results; } else { @@ -948,7 +986,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Sse2.cmpgt_epi16(left, right)); + v128 results = RegisterConversion.IsTrue16(Sse2.cmpgt_epi16(left, right)); + + return *(bool2*)&results; } else { @@ -962,7 +1002,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); + v128 results = RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); + + return *(bool2*)&results; } else { @@ -975,7 +1017,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Sse2.cmpgt_epi16(left, right)); + v128 results = RegisterConversion.IsFalse16(Sse2.cmpgt_epi16(left, right)); + + return *(bool2*)&results; } else { @@ -988,7 +1032,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Xse.cmplt_epi16(left, right)); + v128 results = RegisterConversion.IsFalse16(Xse.cmplt_epi16(left, right)); + + return *(bool2*)&results; } else { diff --git a/Runtime/Math Lib/Types/Vectors/short/short3.cs b/Runtime/Math Lib/Types/Vectors/short/short3.cs index 0a4677c..2ff47f3 100644 --- a/Runtime/Math Lib/Types/Vectors/short/short3.cs +++ b/Runtime/Math Lib/Types/Vectors/short/short3.cs @@ -33,8 +33,6 @@ public DebuggerProxy(short3 v) } - [FieldOffset(0)] private fixed short asArray[3]; - [FieldOffset(0)] public short x; [FieldOffset(2)] public short y; [FieldOffset(4)] public short z; @@ -90,7 +88,7 @@ public short3(short2 xy, short z) { if (Sse4_1.IsSse41Supported) { - this = Sse2.insert_epi16(xy, z, 2); + this = Xse.insert_epi16(xy, (ushort)z, 2); } else { @@ -105,7 +103,7 @@ public short3(short x, short2 yz) { if (Sse4_1.IsSse41Supported) { - this = Sse2.insert_epi16(Sse2.bslli_si128(yz, sizeof(short)), x, 0); + this = Xse.insert_epi16(Sse2.bslli_si128(yz, sizeof(short)), (ushort)x, 0); } else { @@ -1977,10 +1975,29 @@ public readonly short2 zz [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(short3 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(short3 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.SShort0 = input.x; + result.SShort1 = input.y; + result.SShort2 = input.z; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator short3(v128 input) => RegisterConversion.ToType(input); + public static implicit operator short3(v128 input) => new short3 { x = input.SShort0, y = input.SShort1, z = input.SShort2 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator short3(short input) => new short3(input); @@ -2074,7 +2091,7 @@ public static implicit operator int3(short3 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi16_epi32(input)); + return RegisterConversion.ToInt3(Xse.cvtepi16_epi32(input)); } else { @@ -2087,7 +2104,7 @@ public static explicit operator uint3(short3 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi16_epi32(input)); + return RegisterConversion.ToUInt3(Xse.cvtepi16_epi32(input)); } else { @@ -2137,7 +2154,7 @@ public static implicit operator float3(short3 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi16_ps(input)); + return RegisterConversion.ToFloat3(Xse.cvtepi16_ps(input)); } else { @@ -2156,7 +2173,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 3); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return (short)Xse.extract_epi16(this, (byte)index); + } + else + { + short3 onStack = this; + + return *((short*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -2164,7 +2190,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 3); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi16(this, (ushort)value, (byte)index); + } + else + { + short3 onStack = this; + *((short*)&onStack + index) = value; + this = onStack; + } } } @@ -2406,7 +2441,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); + v128 results = RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); + + return *(bool3*)&results; } else { @@ -2419,7 +2456,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmplt_epi16(left, right)); + v128 results = RegisterConversion.IsTrue16(Xse.cmplt_epi16(left, right)); + + return *(bool3*)&results; } else { @@ -2432,7 +2471,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Sse2.cmpgt_epi16(left, right)); + v128 results = RegisterConversion.IsTrue16(Sse2.cmpgt_epi16(left, right)); + + return *(bool3*)&results; } else { @@ -2446,7 +2487,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); + v128 results = RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); + + return *(bool3*)&results; } else { @@ -2459,7 +2502,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Sse2.cmpgt_epi16(left, right)); + v128 results = RegisterConversion.IsFalse16(Sse2.cmpgt_epi16(left, right)); + + return *(bool3*)&results; } else { @@ -2472,7 +2517,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Xse.cmplt_epi16(left, right)); + v128 results = RegisterConversion.IsFalse16(Xse.cmplt_epi16(left, right)); + + return *(bool3*)&results; } else { diff --git a/Runtime/Math Lib/Types/Vectors/short/short4.cs b/Runtime/Math Lib/Types/Vectors/short/short4.cs index 186af0d..8ab4d65 100644 --- a/Runtime/Math Lib/Types/Vectors/short/short4.cs +++ b/Runtime/Math Lib/Types/Vectors/short/short4.cs @@ -35,11 +35,6 @@ public DebuggerProxy(short4 v) } - [FieldOffset(0)] private fixed short asArray[4]; - - // otherhwise LLVM/Burst goes crazy with bitshifts and masks etc. -.- - [FieldOffset(0)] internal long alias_long; - [FieldOffset(0)] public short x; [FieldOffset(2)] public short y; [FieldOffset(4)] public short z; @@ -106,7 +101,7 @@ public short4(short2 xy, short z, short w) { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(Sse2.insert_epi16(xy, z, 2), w, 3); + this = Xse.insert_epi16(Xse.insert_epi16(xy, (ushort)z, 2), (ushort)w, 3); } else { @@ -125,7 +120,7 @@ public short4(short x, short2 yz, short w) { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(Sse2.insert_epi16(Sse2.bslli_si128(yz, sizeof(short)), x, 0), w, 3); + this = Xse.insert_epi16(Xse.insert_epi16(Sse2.bslli_si128(yz, sizeof(short)), (ushort)x, 0), (ushort)w, 3); } else { @@ -182,7 +177,7 @@ public short4(short3 xyz, short w) { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(xyz, w, 3); + this = Xse.insert_epi16(xyz, (ushort)w, 3); } else { @@ -201,7 +196,7 @@ public short4(short x, short3 yzw) { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(Sse2.bslli_si128(yzw, sizeof(short)), x, 0); + this = Xse.insert_epi16(Sse2.bslli_si128(yzw, sizeof(short)), (ushort)x, 0); } else { @@ -5912,12 +5907,32 @@ public readonly short2 ww } #endregion - + [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(short4 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(short4 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.SShort0 = input.x; + result.SShort1 = input.y; + result.SShort2 = input.z; + result.SShort3 = input.w; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator short4(v128 input) => RegisterConversion.ToType(input); + public static implicit operator short4(v128 input) => new short4 { x = input.SShort0, y = input.SShort1, z = input.SShort2, w = input.SShort3 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator short4(short input) => new short4(input); @@ -6011,7 +6026,7 @@ public static implicit operator int4(short4 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi16_epi32(input)); + return RegisterConversion.ToInt4(Xse.cvtepi16_epi32(input)); } else { @@ -6024,7 +6039,7 @@ public static explicit operator uint4(short4 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi16_epi32(input)); + return RegisterConversion.ToUInt4(Xse.cvtepi16_epi32(input)); } else { @@ -6074,7 +6089,7 @@ public static implicit operator float4(short4 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepi16_ps(input)); + return RegisterConversion.ToFloat4(Xse.cvtepi16_ps(input)); } else { @@ -6093,7 +6108,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 4); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return (short)Xse.extract_epi16(this, (byte)index); + } + else + { + short4 onStack = this; + + return *((short*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -6101,7 +6125,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 4); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi16(this, (ushort)value, (byte)index); + } + else + { + short4 onStack = this; + *((short*)&onStack + index) = value; + this = onStack; + } } } @@ -6343,7 +6376,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); + v128 results = RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); + + return *(bool4*)&results; } else { @@ -6356,7 +6391,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmplt_epi16(left, right)); + v128 results = RegisterConversion.IsTrue16(Xse.cmplt_epi16(left, right)); + + return *(bool4*)&results; } else { @@ -6369,7 +6406,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Sse2.cmpgt_epi16(left, right)); + v128 results = RegisterConversion.IsTrue16(Sse2.cmpgt_epi16(left, right)); + + return *(bool4*)&results; } else { @@ -6383,7 +6422,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); + v128 results = RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); + + return *(bool4*)&results; } else { @@ -6396,7 +6437,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Sse2.cmpgt_epi16(left, right)); + v128 results = RegisterConversion.IsFalse16(Sse2.cmpgt_epi16(left, right)); + + return *(bool4*)&results; } else { @@ -6409,7 +6452,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Xse.cmplt_epi16(left, right)); + v128 results = RegisterConversion.IsFalse16(Xse.cmplt_epi16(left, right)); + + return *(bool4*)&results; } else { diff --git a/Runtime/Math Lib/Types/Vectors/short/short8.cs b/Runtime/Math Lib/Types/Vectors/short/short8.cs index d250628..6776efa 100644 --- a/Runtime/Math Lib/Types/Vectors/short/short8.cs +++ b/Runtime/Math Lib/Types/Vectors/short/short8.cs @@ -43,8 +43,6 @@ public DebuggerProxy(short8 v) } - [FieldOffset(0)] private fixed short asArray[8]; - [FieldOffset(0)] public short x0; [FieldOffset(2)] public short x1; [FieldOffset(4)] public short x2; @@ -820,10 +818,11 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(short8 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(short8 input) => new v128 { SShort0 = input.x0, SShort1 = input.x1, SShort2 = input.x2, SShort3 = input.x3, SShort4 = input.x4, SShort5 = input.x5, SShort6 = input.x6, SShort7 = input.x7 }; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator short8(v128 input) => RegisterConversion.ToType(input); + public static implicit operator short8(v128 input) => new short8 { x0 = input.SShort0, x1 = input.SShort1, x2 = input.SShort2, x3 = input.SShort3, x4 = input.SShort4, x5 = input.SShort5, x6 = input.SShort6, x7 = input.SShort7 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator short8(short input) => new short8(input); @@ -923,7 +922,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 8); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return (short)Xse.extract_epi16(this, (byte)index); + } + else + { + short8 onStack = this; + + return *((short*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -931,7 +939,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 8); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi16(this, (ushort)value, (byte)index); + } + else + { + short8 onStack = this; + *((short*)&onStack + index) = value; + this = onStack; + } } } @@ -978,26 +995,26 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short8 operator / (short8 left, short8 right) { - if (Avx.IsAvxSupported) + if (Sse2.IsSse2Supported) { return Xse.div_epi16(left, right, false, 8); } else { - return new short8(left.v4_0 / right.v4_0, left.v4_4 / right.v4_4); + return new short8((short)(left.x0 / right.x0), (short)(left.x1 / right.x1), (short)(left.x2 / right.x2), (short)(left.x3 / right.x3), (short)(left.x4 / right.x4), (short)(left.x5 / right.x5), (short)(left.x6 / right.x6), (short)(left.x7 / right.x7)); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short8 operator % (short8 left, short8 right) { - if (Avx2.IsAvx2Supported) + if (Sse2.IsSse2Supported) { return Xse.rem_epi16(left, right, 8); } else { - return new short8(left.v4_0 % right.v4_0, left.v4_4 % right.v4_4); + return new short8((short)(left.x0 % right.x0), (short)(left.x1 % right.x1), (short)(left.x2 % right.x2), (short)(left.x3 % right.x3), (short)(left.x4 % right.x4), (short)(left.x5 % right.x5), (short)(left.x6 % right.x6), (short)(left.x7 % right.x7)); } } @@ -1173,7 +1190,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); + return RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); } else { @@ -1186,7 +1203,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmplt_epi16(left, right)); + return RegisterConversion.IsTrue16(Xse.cmplt_epi16(left, right)); } else { @@ -1199,7 +1216,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Sse2.cmpgt_epi16(left, right)); + return RegisterConversion.IsTrue16(Sse2.cmpgt_epi16(left, right)); } else { @@ -1213,7 +1230,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); + return RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); } else { @@ -1226,7 +1243,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Sse2.cmpgt_epi16(left, right)); + return RegisterConversion.IsFalse16(Sse2.cmpgt_epi16(left, right)); } else { @@ -1239,7 +1256,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Xse.cmplt_epi16(left, right)); + return RegisterConversion.IsFalse16(Xse.cmplt_epi16(left, right)); } else { diff --git a/Runtime/Math Lib/Types/Vectors/short/ushort16.cs b/Runtime/Math Lib/Types/Vectors/short/ushort16.cs index 10b10d2..e275ab5 100644 --- a/Runtime/Math Lib/Types/Vectors/short/ushort16.cs +++ b/Runtime/Math Lib/Types/Vectors/short/ushort16.cs @@ -57,8 +57,6 @@ public DebuggerProxy(ushort16 v) } - [FieldOffset(0)] private fixed ushort asArray[16]; - [FieldOffset(0)] internal ushort8 _v8_0; [FieldOffset(16)] internal ushort8 _v8_8; @@ -136,7 +134,7 @@ public ushort16(ushort4 x0123, ushort3 x456, ushort3 x789, ushort3 x10_11_12, us if (Sse2.IsSse2Supported) { - lo = Sse2.insert_epi16(Sse2.unpacklo_epi64(x0123, x456), x789.x, 7); + lo = Xse.insert_epi16(Sse2.unpacklo_epi64(x0123, x456), x789.x, 7); } else { @@ -2017,10 +2015,11 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v256(ushort16 input) => RegisterConversion.ToV256(input); + public static implicit operator v256(ushort16 input) => new v256{ UShort0 = input.x0, UShort1 = input.x1, UShort2 = input.x2, UShort3 = input.x3, UShort4 = input.x4, UShort5 = input.x5, UShort6 = input.x6, UShort7 = input.x7, UShort8 = input.x8, UShort9 = input.x9, UShort10 = input.x10, UShort11 = input.x11, UShort12 = input.x12, UShort13 = input.x13, UShort14 = input.x14, UShort15 = input.x15 }; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator ushort16(v256 input) => RegisterConversion.ToType(input); + public static implicit operator ushort16(v256 input) => new ushort16{ x0 = input.UShort0, x1 = input.UShort1, x2 = input.UShort2, x3 = input.UShort3, x4 = input.UShort4, x5 = input.UShort5, x6 = input.UShort6, x7 = input.UShort7, x8 = input.UShort8, x9 = input.UShort9, x10 = input.UShort10, x11 = input.UShort11, x12 = input.UShort12, x13 = input.UShort13, x14 = input.UShort14, x15 = input.UShort15 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator ushort16(ushort input) => new ushort16(input); @@ -2051,15 +2050,61 @@ readonly get { Assert.IsWithinArrayBounds(index, 16); - return asArray[index]; + if (Avx2.IsAvx2Supported) + { + return Xse.mm256_extract_epi16(this, (byte)index); + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 8) + { + return Xse.extract_epi16(_v8_0, (byte)index); + } + else + { + return Xse.extract_epi16(_v8_8, (byte)(index - 8)); + } + } + } + + ushort16 onStack = this; + + return *((ushort*)&onStack + index); } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { Assert.IsWithinArrayBounds(index, 16); + + if (Avx2.IsAvx2Supported) + { + this = Xse.mm256_insert_epi16(this, value, (byte)index); + + return; + } + else if (Sse2.IsSse2Supported) + { + if (Constant.IsConstantExpression(index)) + { + if (index < 8) + { + _v8_0 = Xse.insert_epi16(_v8_0, value, (byte)index); + } + else + { + _v8_8 = Xse.insert_epi16(_v8_8, value, (byte)(index - 8)); + } + + return; + } + } - asArray[index] = value; + ushort16 onStack = this; + *((ushort*)&onStack + index) = value; + this = onStack; } } diff --git a/Runtime/Math Lib/Types/Vectors/short/ushort2.cs b/Runtime/Math Lib/Types/Vectors/short/ushort2.cs index 9f839d8..aca5ac6 100644 --- a/Runtime/Math Lib/Types/Vectors/short/ushort2.cs +++ b/Runtime/Math Lib/Types/Vectors/short/ushort2.cs @@ -31,8 +31,6 @@ public DebuggerProxy(ushort2 v) } - [FieldOffset(0)] private fixed ushort asArray[2]; - [FieldOffset(0)] public ushort x; [FieldOffset(2)] public ushort y; @@ -51,7 +49,7 @@ public ushort2(ushort x, ushort y) } else { - this = Sse2.insert_epi16(Sse2.cvtsi32_si128(x), y, 1); + this = Xse.insert_epi16(Sse2.cvtsi32_si128(x), y, 1); } } else @@ -499,10 +497,28 @@ public readonly ushort2 yy [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(ushort2 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(ushort2 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.UShort0 = input.x; + result.UShort1 = input.y; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator ushort2(v128 input) => RegisterConversion.ToType(input); + public static implicit operator ushort2(v128 input) => new ushort2 { x = input.UShort0, y = input.UShort1 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator ushort2(ushort input) => new ushort2(input); @@ -588,7 +604,7 @@ public static implicit operator int2(ushort2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu16_epi32(input)); + return RegisterConversion.ToInt2(Xse.cvtepu16_epi32(input)); } else { @@ -601,7 +617,7 @@ public static implicit operator uint2(ushort2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType( Xse.cvtepu16_epi32(input)); + return RegisterConversion.ToUInt2( Xse.cvtepu16_epi32(input)); } else { @@ -643,7 +659,7 @@ public static implicit operator float2(ushort2 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu16_ps(input)); + return RegisterConversion.ToFloat2(Xse.cvtepu16_ps(input)); } else { @@ -662,7 +678,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 2); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return Xse.extract_epi16(this, (byte)index); + } + else + { + ushort2 onStack = this; + + return *((ushort*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -670,7 +695,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 2); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi16(this, value, (byte)index); + } + else + { + ushort2 onStack = this; + *((ushort*)&onStack + index) = value; + this = onStack; + } } } @@ -899,7 +933,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); + v128 results = RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); + + return *(bool2*)&results; } else { @@ -912,7 +948,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmplt_epu16(left, right, 2)); + v128 results = RegisterConversion.IsTrue16(Xse.cmplt_epu16(left, right, 2)); + + return *(bool2*)&results; } else { @@ -925,7 +963,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmpgt_epu16(left, right, 2)); + v128 results = RegisterConversion.IsTrue16(Xse.cmpgt_epu16(left, right, 2)); + + return *(bool2*)&results; } else { @@ -939,7 +979,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); + v128 results = RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); + + return *(bool2*)&results; } else { @@ -952,7 +994,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmple_epu16(left, right, 2)); + v128 results = RegisterConversion.IsTrue16(Xse.cmple_epu16(left, right, 2)); + + return *(bool2*)&results; } else { @@ -965,7 +1009,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmpge_epu16(left, right, 2)); + v128 results = RegisterConversion.IsTrue16(Xse.cmpge_epu16(left, right, 2)); + + return *(bool2*)&results; } else { diff --git a/Runtime/Math Lib/Types/Vectors/short/ushort3.cs b/Runtime/Math Lib/Types/Vectors/short/ushort3.cs index a65120d..3c8d793 100644 --- a/Runtime/Math Lib/Types/Vectors/short/ushort3.cs +++ b/Runtime/Math Lib/Types/Vectors/short/ushort3.cs @@ -33,8 +33,6 @@ public DebuggerProxy(ushort3 v) } - [FieldOffset(0)] private fixed ushort asArray[3]; - [FieldOffset(0)] public ushort x; [FieldOffset(2)] public ushort y; [FieldOffset(4)] public ushort z; @@ -90,7 +88,7 @@ public ushort3(ushort2 xy, ushort z) { if (Sse4_1.IsSse41Supported) { - this = Sse2.insert_epi16(xy, z, 2); + this = Xse.insert_epi16(xy, z, 2); } else { @@ -105,7 +103,7 @@ public ushort3(ushort x, ushort2 yz) { if (Sse4_1.IsSse41Supported) { - this = Sse2.insert_epi16(Sse2.bslli_si128(yz, sizeof(ushort)), x, 0); + this = Xse.insert_epi16(Sse2.bslli_si128(yz, sizeof(ushort)), x, 0); } else { @@ -1977,10 +1975,29 @@ public readonly ushort2 zz [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(ushort3 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(ushort3 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.UShort0 = input.x; + result.UShort1 = input.y; + result.UShort2 = input.z; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator ushort3(v128 input) => RegisterConversion.ToType(input); + public static implicit operator ushort3(v128 input) => new ushort3 { x = input.UShort0, y = input.UShort1, z = input.UShort2 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator ushort3(ushort input) => new ushort3(input); @@ -2074,7 +2091,7 @@ public static implicit operator int3(ushort3 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu16_epi32(input)); + return RegisterConversion.ToInt3(Xse.cvtepu16_epi32(input)); } else { @@ -2087,7 +2104,7 @@ public static implicit operator uint3(ushort3 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu16_epi32(input)); + return RegisterConversion.ToUInt3(Xse.cvtepu16_epi32(input)); } else { @@ -2137,7 +2154,7 @@ public static implicit operator float3(ushort3 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu16_ps(input)); + return RegisterConversion.ToFloat3(Xse.cvtepu16_ps(input)); } else { @@ -2156,7 +2173,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 3); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return Xse.extract_epi16(this, (byte)index); + } + else + { + ushort3 onStack = this; + + return *((ushort*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -2164,7 +2190,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 3); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi16(this, value, (byte)index); + } + else + { + ushort3 onStack = this; + *((ushort*)&onStack + index) = value; + this = onStack; + } } } @@ -2393,7 +2428,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); + v128 results = RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); + + return *(bool3*)&results; } else { @@ -2406,7 +2443,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmplt_epu16(left, right, 3)); + v128 results = RegisterConversion.IsTrue16(Xse.cmplt_epu16(left, right, 3)); + + return *(bool3*)&results; } else { @@ -2419,7 +2458,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmpgt_epu16(left, right, 3)); + v128 results = RegisterConversion.IsTrue16(Xse.cmpgt_epu16(left, right, 3)); + + return *(bool3*)&results; } else { @@ -2433,7 +2474,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); + v128 results = RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); + + return *(bool3*)&results; } else { @@ -2446,7 +2489,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmple_epu16(left, right, 3)); + v128 results = RegisterConversion.IsTrue16(Xse.cmple_epu16(left, right, 3)); + + return *(bool3*)&results; } else { @@ -2459,7 +2504,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmpge_epu16(left, right, 3)); + v128 results = RegisterConversion.IsTrue16(Xse.cmpge_epu16(left, right, 3)); + + return *(bool3*)&results; } else { diff --git a/Runtime/Math Lib/Types/Vectors/short/ushort4.cs b/Runtime/Math Lib/Types/Vectors/short/ushort4.cs index b917251..8c56383 100644 --- a/Runtime/Math Lib/Types/Vectors/short/ushort4.cs +++ b/Runtime/Math Lib/Types/Vectors/short/ushort4.cs @@ -35,11 +35,6 @@ public DebuggerProxy(ushort4 v) } - [FieldOffset(0)] private fixed ushort asArray[4]; - - // otherhwise LLVM/Burst goes crazy with bitshifts and masks etc. -.- - [FieldOffset(0)] internal long alias_long; - [FieldOffset(0)] public ushort x; [FieldOffset(2)] public ushort y; [FieldOffset(4)] public ushort z; @@ -106,7 +101,7 @@ public ushort4(ushort2 xy, ushort z, ushort w) { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(Sse2.insert_epi16(xy, z, 2), w, 3); + this = Xse.insert_epi16(Xse.insert_epi16(xy, z, 2), w, 3); } else { @@ -125,7 +120,7 @@ public ushort4(ushort x, ushort2 yz, ushort w) { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(Sse2.insert_epi16(Sse2.bslli_si128(yz, sizeof(ushort)), x, 0), w, 3); + this = Xse.insert_epi16(Xse.insert_epi16(Sse2.bslli_si128(yz, sizeof(ushort)), x, 0), w, 3); } else { @@ -182,7 +177,7 @@ public ushort4(ushort3 xyz, ushort w) { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(xyz, w, 3); + this = Xse.insert_epi16(xyz, w, 3); } else { @@ -201,7 +196,7 @@ public ushort4(ushort x, ushort3 yzw) { if (Sse2.IsSse2Supported) { - this = Sse2.insert_epi16(Sse2.bslli_si128(yzw, sizeof(ushort)), x, 0); + this = Xse.insert_epi16(Sse2.bslli_si128(yzw, sizeof(ushort)), x, 0); } else { @@ -5914,10 +5909,30 @@ public readonly ushort2 ww [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(ushort4 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(ushort4 input) + { + v128 result; + + if (Avx.IsAvxSupported) + { + result = Avx.undefined_si128(); + } + else + { + v128* dummyPtr = &result; + } + + result.UShort0 = input.x; + result.UShort1 = input.y; + result.UShort2 = input.z; + result.UShort3 = input.w; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator ushort4(v128 input) => RegisterConversion.ToType(input); + public static implicit operator ushort4(v128 input) => new ushort4 { x = input.UShort0, y = input.UShort1, z = input.UShort2, w = input.UShort3 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator ushort4(ushort input) => new ushort4(input); @@ -6011,7 +6026,7 @@ public static implicit operator int4(ushort4 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu16_epi32(input)); + return RegisterConversion.ToInt4(Xse.cvtepu16_epi32(input)); } else { @@ -6024,7 +6039,7 @@ public static implicit operator uint4(ushort4 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu16_epi32(input)); + return RegisterConversion.ToUInt4(Xse.cvtepu16_epi32(input)); } else { @@ -6074,7 +6089,7 @@ public static implicit operator float4(ushort4 input) { if (Sse2.IsSse2Supported) { - return RegisterConversion.ToType(Xse.cvtepu16_ps(input)); + return RegisterConversion.ToFloat4(Xse.cvtepu16_ps(input)); } else { @@ -6093,15 +6108,33 @@ readonly get { Assert.IsWithinArrayBounds(index, 4); - return asArray[index]; - } + if (Sse2.IsSse2Supported) + { + return Xse.extract_epi16(this, (byte)index); + } + else + { + ushort4 onStack = this; + return *((ushort*)&onStack + index); + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] set { Assert.IsWithinArrayBounds(index, 4); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi16(this, value, (byte)index); + } + else + { + ushort4 onStack = this; + *((ushort*)&onStack + index) = value; + this = onStack; + } } } @@ -6330,7 +6363,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); + v128 results = RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); + + return *(bool4*)&results; } else { @@ -6343,7 +6378,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmplt_epu16(left, right, 4)); + v128 results = RegisterConversion.IsTrue16(Xse.cmplt_epu16(left, right, 4)); + + return *(bool4*)&results; } else { @@ -6356,7 +6393,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmpgt_epu16(left, right, 4)); + v128 results = RegisterConversion.IsTrue16(Xse.cmpgt_epu16(left, right, 4)); + + return *(bool4*)&results; } else { @@ -6370,7 +6409,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); + v128 results = RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); + + return *(bool4*)&results; } else { @@ -6383,7 +6424,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmple_epu16(left, right, 4)); + v128 results = RegisterConversion.IsTrue16(Xse.cmple_epu16(left, right, 4)); + + return *(bool4*)&results; } else { @@ -6396,7 +6439,9 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmpge_epu16(left, right, 4)); + v128 results = RegisterConversion.IsTrue16(Xse.cmpge_epu16(left, right, 4)); + + return *(bool4*)&results; } else { diff --git a/Runtime/Math Lib/Types/Vectors/short/ushort8.cs b/Runtime/Math Lib/Types/Vectors/short/ushort8.cs index e843c81..56253f6 100644 --- a/Runtime/Math Lib/Types/Vectors/short/ushort8.cs +++ b/Runtime/Math Lib/Types/Vectors/short/ushort8.cs @@ -43,8 +43,6 @@ public DebuggerProxy(ushort8 v) } - [FieldOffset(0)] private fixed ushort asArray[8]; - [FieldOffset(0)] public ushort x0; [FieldOffset(2)] public ushort x1; [FieldOffset(4)] public ushort x2; @@ -827,12 +825,13 @@ readonly get } #endregion - + [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator v128(ushort8 input) => RegisterConversion.ToV128(input); + public static implicit operator v128(ushort8 input) => new v128 { UShort0 = input.x0, UShort1 = input.x1, UShort2 = input.x2, UShort3 = input.x3, UShort4 = input.x4, UShort5 = input.x5, UShort6 = input.x6, UShort7 = input.x7 }; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator ushort8(v128 input) => RegisterConversion.ToType(input); + public static implicit operator ushort8(v128 input) => new ushort8 { x0 = input.UShort0, x1 = input.UShort1, x2 = input.UShort2, x3 = input.UShort3, x4 = input.UShort4, x5 = input.UShort5, x6 = input.UShort6, x7 = input.UShort7 }; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator ushort8(ushort input) => new ushort8(input); @@ -946,7 +945,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 8); - return asArray[index]; + if (Sse2.IsSse2Supported) + { + return Xse.extract_epi16(this, (byte)index); + } + else + { + ushort8 onStack = this; + + return *((ushort*)&onStack + index); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -954,7 +962,16 @@ readonly get { Assert.IsWithinArrayBounds(index, 8); - asArray[index] = value; + if (Sse2.IsSse2Supported) + { + this = Xse.insert_epi16(this, value, (byte)index); + } + else + { + ushort8 onStack = this; + *((ushort*)&onStack + index) = value; + this = onStack; + } } } @@ -1007,20 +1024,20 @@ readonly get } else { - return new ushort8(left.v4_0 / right.v4_0, left.v4_4 / right.v4_4); + return new ushort8((ushort)(left.x0 / right.x0), (ushort)(left.x1 / right.x1), (ushort)(left.x2 / right.x2), (ushort)(left.x3 / right.x3), (ushort)(left.x4 / right.x4), (ushort)(left.x5 / right.x5), (ushort)(left.x6 / right.x6), (ushort)(left.x7 / right.x7)); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort8 operator % (ushort8 left, ushort8 right) { - if (Avx2.IsAvx2Supported) + if (Sse2.IsSse2Supported) { return Xse.rem_epu16(left, right); } else { - return new ushort8(left.v4_0 % right.v4_0, left.v4_4 % right.v4_4); + return new ushort8((ushort)(left.x0 % right.x0), (ushort)(left.x1 % right.x1), (ushort)(left.x2 % right.x2), (ushort)(left.x3 % right.x3), (ushort)(left.x4 % right.x4), (ushort)(left.x5 % right.x5), (ushort)(left.x6 % right.x6), (ushort)(left.x7 % right.x7)); } } @@ -1183,7 +1200,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); + return RegisterConversion.IsTrue16(Sse2.cmpeq_epi16(left, right)); } else { @@ -1196,7 +1213,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmplt_epu16(left, right, 8)); + return RegisterConversion.IsTrue16(Xse.cmplt_epu16(left, right, 8)); } else { @@ -1209,7 +1226,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmpgt_epu16(left, right, 8)); + return RegisterConversion.IsTrue16(Xse.cmpgt_epu16(left, right, 8)); } else { @@ -1223,7 +1240,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); + return RegisterConversion.IsFalse16(Sse2.cmpeq_epi16(left, right)); } else { @@ -1236,7 +1253,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmple_epu16(left, right, 8)); + return RegisterConversion.IsTrue16(Xse.cmple_epu16(left, right, 8)); } else { @@ -1249,7 +1266,7 @@ readonly get { if (Sse2.IsSse2Supported) { - return RegisterConversion.IsTrue16(Xse.cmpge_epu16(left, right, 8)); + return RegisterConversion.IsTrue16(Xse.cmpge_epu16(left, right, 8)); } else { diff --git a/Runtime/Math Lib/Types/ctor wrappers.cs b/Runtime/Math Lib/Types/ctor wrappers.cs index 3390e64..d192ec0 100644 --- a/Runtime/Math Lib/Types/ctor wrappers.cs +++ b/Runtime/Math Lib/Types/ctor wrappers.cs @@ -3,7 +3,7 @@ namespace MaxMath { - unsafe public static partial class maxmath + unsafe public static partial class maxmath { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool16 bool16(bool x0, bool x1, bool x2, bool x3, bool x4, bool x5, bool x6, bool x7, bool x8, bool x9, bool x10, bool x11, bool x12, bool x13, bool x14, bool x15) => new bool16(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15); diff --git a/Runtime/XSE Core/Basic Operations.meta b/Runtime/XSE Core/Basic Mathematical Operations.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations.meta rename to Runtime/XSE Core/Basic Mathematical Operations.meta diff --git a/Runtime/XSE Core/Basic Operations/Bit Shifting.cs b/Runtime/XSE Core/Basic Mathematical Operations/Bit Shifting.cs similarity index 84% rename from Runtime/XSE Core/Basic Operations/Bit Shifting.cs rename to Runtime/XSE Core/Basic Mathematical Operations/Bit Shifting.cs index 9ce7fb0..2626892 100644 --- a/Runtime/XSE Core/Basic Operations/Bit Shifting.cs +++ b/Runtime/XSE Core/Basic Mathematical Operations/Bit Shifting.cs @@ -83,7 +83,7 @@ public static v256 mm256_srli_epi8(v256 x, int n) [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v128 srai_epi8(v128 x, int n) + public static v128 srai_epi8(v128 x, int n, byte elements = 16) { if (Sse2.IsSse2Supported) { @@ -92,10 +92,17 @@ public static v128 srai_epi8(v128 x, int n) return Sse2.cmpgt_epi8(Sse2.setzero_si128(), x); } - v128 even = srai_epi16(slli_epi16(x, 8), n + 8); - v128 odd = srai_epi16(x, n); + if (Sse4_1.IsSse41Supported && elements <= 8) + { + return cvtepi16_epi8(srai_epi16(Sse4_1.cvtepi8_epi16(x), n)); + } + else + { + v128 even = srai_epi16(slli_epi16(x, 8), n + 8); + v128 odd = srai_epi16(x, n); - return Xse.blendv_si128(even, odd, new v128(0xFF00_FF00)); + return blendv_si128(even, odd, new v128(0xFF00_FF00)); + } } else throw new IllegalInstructionException(); } @@ -113,7 +120,7 @@ public static v256 mm256_srai_epi8(v256 x, int n) v256 even = mm256_srai_epi16(mm256_slli_epi16(x, 8), n + 8); v256 odd = mm256_srai_epi16(x, n); - return Xse.mm256_blendv_si256(even, odd, new v256(0xFF00_FF00)); + return mm256_blendv_si256(even, odd, new v256(0xFF00_FF00)); } else throw new IllegalInstructionException(); } @@ -124,7 +131,7 @@ public static v128 slli_epi16(v128 x, int n) { if (Sse2.IsSse2Supported) { - return Sse2.sll_epi16(x, new v128(n, 0, 0, 0)); + return Sse2.sll_epi16(x, Sse2.cvtsi32_si128(n)); } else throw new IllegalInstructionException(); } @@ -134,7 +141,7 @@ public static v256 mm256_slli_epi16(v256 x, int n) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_sll_epi16(x, new v128(n, 0, 0, 0)); + return Avx2.mm256_sll_epi16(x, Sse2.cvtsi32_si128(n)); } else throw new IllegalInstructionException(); } @@ -144,7 +151,7 @@ public static v128 srli_epi16(v128 x, int n) { if (Sse2.IsSse2Supported) { - return Sse2.srl_epi16(x, new v128(n, 0, 0, 0)); + return Sse2.srl_epi16(x, Sse2.cvtsi32_si128(n)); } else throw new IllegalInstructionException(); } @@ -154,7 +161,7 @@ public static v256 mm256_srli_epi16(v256 x, int n) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_srl_epi16(x, new v128(n, 0, 0, 0)); + return Avx2.mm256_srl_epi16(x, Sse2.cvtsi32_si128(n)); } else throw new IllegalInstructionException(); } @@ -164,7 +171,7 @@ public static v128 srai_epi16(v128 x, int n) { if (Sse2.IsSse2Supported) { - return Sse2.sra_epi16(x, new v128(n, 0, 0, 0)); + return Sse2.sra_epi16(x, Sse2.cvtsi32_si128(n)); } else throw new IllegalInstructionException(); } @@ -174,7 +181,7 @@ public static v256 mm256_srai_epi16(v256 x, int n) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_sra_epi16(x, new v128(n, 0, 0, 0)); + return Avx2.mm256_sra_epi16(x, Sse2.cvtsi32_si128(n)); } else throw new IllegalInstructionException(); } @@ -185,7 +192,7 @@ public static v128 srai_epi32(v128 x, int n) { if (Sse2.IsSse2Supported) { - return Sse2.sra_epi32(x, new v128(n, 0, 0, 0)); + return Sse2.sra_epi32(x, Sse2.cvtsi32_si128(n)); } else throw new IllegalInstructionException(); } @@ -195,7 +202,7 @@ public static v256 mm256_srai_epi32(v256 x, int n) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_sra_epi32(x, new v128(n, 0, 0, 0)); + return Avx2.mm256_sra_epi32(x, Sse2.cvtsi32_si128(n)); } else throw new IllegalInstructionException(); } @@ -205,7 +212,7 @@ public static v128 srli_epi32(v128 x, int n) { if (Sse2.IsSse2Supported) { - return Sse2.srl_epi32(x, new v128(n, 0, 0, 0)); + return Sse2.srl_epi32(x, Sse2.cvtsi32_si128(n)); } else throw new IllegalInstructionException(); } @@ -215,7 +222,7 @@ public static v256 mm256_srli_epi32(v256 x, int n) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_srl_epi32(x, new v128(n, 0, 0, 0)); + return Avx2.mm256_srl_epi32(x, Sse2.cvtsi32_si128(n)); } else throw new IllegalInstructionException(); } @@ -225,7 +232,7 @@ public static v128 slli_epi32(v128 x, int n) { if (Sse2.IsSse2Supported) { - return Sse2.sll_epi32(x, new v128(n, 0, 0, 0)); + return Sse2.sll_epi32(x, Sse2.cvtsi32_si128(n)); } else throw new IllegalInstructionException(); } @@ -235,7 +242,7 @@ public static v256 mm256_slli_epi32(v256 x, int n) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_sll_epi32(x, new v128(n, 0, 0, 0)); + return Avx2.mm256_sll_epi32(x, Sse2.cvtsi32_si128(n)); } else throw new IllegalInstructionException(); } @@ -246,7 +253,7 @@ public static v128 slli_epi64(v128 x, int n) { if (Sse2.IsSse2Supported) { - return Sse2.sll_epi64(x, new v128(n, 0, 0, 0)); + return Sse2.sll_epi64(x, Sse2.cvtsi32_si128(n)); } else throw new IllegalInstructionException(); } @@ -256,7 +263,7 @@ public static v256 mm256_slli_epi64(v256 x, int n) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_sll_epi64(x, new v128(n, 0, 0, 0)); + return Avx2.mm256_sll_epi64(x, Sse2.cvtsi32_si128(n)); } else throw new IllegalInstructionException(); } @@ -266,7 +273,7 @@ public static v128 srli_epi64(v128 x, int n) { if (Sse2.IsSse2Supported) { - return Sse2.srl_epi64(x, new v128(n, 0, 0, 0)); + return Sse2.srl_epi64(x, Sse2.cvtsi32_si128(n)); } else throw new IllegalInstructionException(); } @@ -276,7 +283,7 @@ public static v256 mm256_srli_epi64(v256 x, int n) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_srl_epi64(x, new v128(n, 0, 0, 0)); + return Avx2.mm256_srl_epi64(x, Sse2.cvtsi32_si128(n)); } else throw new IllegalInstructionException(); } @@ -317,7 +324,7 @@ public static v128 srai_epi64(v128 x, int n) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v256 mm256_srai_epi64(v256 x, int n, byte elements = 4) + public static v256 mm256_srai_epi64(v256 x, int n) { if (Avx2.IsAvx2Supported) { diff --git a/Runtime/XSE Core/Basic Operations/Bit Shifting.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Bit Shifting.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Bit Shifting.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Bit Shifting.cs.meta diff --git a/Runtime/XSE Core/Basic Mathematical Operations/Boolean Logic.cs b/Runtime/XSE Core/Basic Mathematical Operations/Boolean Logic.cs new file mode 100644 index 0000000..07c0bdf --- /dev/null +++ b/Runtime/XSE Core/Basic Mathematical Operations/Boolean Logic.cs @@ -0,0 +1,90 @@ +using System.Runtime.CompilerServices; +using Unity.Burst.Intrinsics; + +using static Unity.Burst.Intrinsics.X86; + +namespace MaxMath.Intrinsics +{ + unsafe public static partial class Xse + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 not_si128(v128 a) + { + if (Sse2.IsSse2Supported) + { + return ternarylogic_si128(a, a, a, TernaryOperation.OxOF); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_not_si256(v256 a) + { + if (Avx2.IsAvx2Supported) + { + return mm256_ternarylogic_si256(a, a, a, TernaryOperation.OxOF); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 ornot_si128(v128 a, v128 b) + { + if (Sse2.IsSse2Supported) + { + return ternarylogic_si128(b, a, a, TernaryOperation.OxF3); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_ornot_si256(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + return mm256_ternarylogic_si256(b, a, a, TernaryOperation.OxF3); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 nor_si128(v128 a, v128 b) + { + if (Sse2.IsSse2Supported) + { + return ternarylogic_si128(a, b, a, TernaryOperation.OxO3); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_nor_si256(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + return mm256_ternarylogic_si256(a, b, a, TernaryOperation.OxO3); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 xnor_si128(v128 a, v128 b) + { + if (Sse2.IsSse2Supported) + { + return ternarylogic_si128(a, b, a, TernaryOperation.OxC3); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_xnor_si256(v256 a, v256 b) + { + if (Avx2.IsAvx2Supported) + { + return mm256_ternarylogic_si256(a, b, a, TernaryOperation.OxC3); + } + else throw new IllegalInstructionException(); + } + } +} diff --git a/Runtime/XSE Core/Basic Operations/NOT.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Boolean Logic.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/NOT.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Boolean Logic.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/Comparison.meta b/Runtime/XSE Core/Basic Mathematical Operations/Comparison.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Comparison.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Comparison.meta diff --git a/Runtime/XSE Core/Basic Operations/Comparison/64 bit SSE2.cs b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/64 bit SSE2.cs similarity index 98% rename from Runtime/XSE Core/Basic Operations/Comparison/64 bit SSE2.cs rename to Runtime/XSE Core/Basic Mathematical Operations/Comparison/64 bit SSE2.cs index 5484ae5..a082d56 100644 --- a/Runtime/XSE Core/Basic Operations/Comparison/64 bit SSE2.cs +++ b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/64 bit SSE2.cs @@ -1,5 +1,4 @@ using System.Runtime.CompilerServices; -using Unity.Burst.CompilerServices; using Unity.Burst.Intrinsics; using static Unity.Burst.Intrinsics.X86; diff --git a/Runtime/XSE Core/Basic Operations/Comparison/64 bit SSE2.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/64 bit SSE2.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Comparison/64 bit SSE2.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Comparison/64 bit SSE2.cs.meta diff --git a/Runtime/XSE Core/Basic Mathematical Operations/Comparison/Float16.cs b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/Float16.cs new file mode 100644 index 0000000..049f710 --- /dev/null +++ b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/Float16.cs @@ -0,0 +1,403 @@ +using System.Runtime.CompilerServices; +using Unity.Burst.Intrinsics; + +using static Unity.Burst.Intrinsics.X86; +using static MaxMath.LUT.FLOATING_POINT; + +namespace MaxMath.Intrinsics +{ + unsafe public static partial class Xse + { + private static v128 F16_ABS_MASK + { + get + { + if (Sse2.IsSse2Supported) + { + return Sse2.set1_epi16(unchecked((short)((1 << (F16_BITS - 1)) - 1))); + } + else throw new IllegalInstructionException(); + } + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpord_ph(v128 a, v128 b, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_LT_EPU16(a, 1 << 15, elements) && constexpr.ALL_LT_EPU16(b, 1 << 15, elements)) + { + return Sse2.and_si128(Sse2.cmpgt_epi16(Sse2.set1_epi16(F16_SIGNALING_EXPONENT + 1), a), + Sse2.cmpgt_epi16(Sse2.set1_epi16(F16_SIGNALING_EXPONENT + 1), b)); + } + else + { + return Sse2.and_si128(Sse2.cmpgt_epi16(Sse2.set1_epi16(F16_SIGNALING_EXPONENT + 1), Sse2.and_si128(a, F16_ABS_MASK)), + Sse2.cmpgt_epi16(Sse2.set1_epi16(F16_SIGNALING_EXPONENT + 1), Sse2.and_si128(b, F16_ABS_MASK))); + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpunord_ph(v128 a, v128 b, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_LT_EPU16(a, 1 << 15, elements) && constexpr.ALL_LT_EPU16(b, 1 << 15, elements)) + { + return Sse2.or_si128(Sse2.cmpgt_epi16(a, Sse2.set1_epi16(F16_SIGNALING_EXPONENT)), + Sse2.cmpgt_epi16(b, Sse2.set1_epi16(F16_SIGNALING_EXPONENT))); + } + else + { + return Sse2.or_si128(Sse2.cmpgt_epi16(Sse2.and_si128(a, F16_ABS_MASK), Sse2.set1_epi16(F16_SIGNALING_EXPONENT)), + Sse2.cmpgt_epi16(Sse2.and_si128(b, F16_ABS_MASK), Sse2.set1_epi16(F16_SIGNALING_EXPONENT))); + } + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpeq_ph(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_EQ_EPU16(a, 0, elements) || constexpr.ALL_EQ_EPU16(a, 0x8000, elements)) + { + if (promiseNeitherNaN) + { + return Sse2.cmpeq_epi16(Sse2.slli_epi16(b, 1), Sse2.setzero_si128()); + } + else + { + return Sse2.andnot_si128(cmpunord_ph(b, b), Sse2.cmpeq_epi16(Sse2.slli_epi16(b, 1), Sse2.setzero_si128())); + } + } + else if (Xse.constexpr.ALL_EQ_EPU16(b, 0, elements) || Xse.constexpr.ALL_EQ_EPU16(b, 0x8000, elements)) + { + if (promiseNeitherNaN) + { + return Sse2.cmpeq_epi16(Sse2.slli_epi16(a, 1), Sse2.setzero_si128()); + } + else + { + return Sse2.andnot_si128(cmpunord_ph(a, a), Sse2.cmpeq_epi16(Sse2.slli_epi16(a, 1), Sse2.setzero_si128())); + } + } + else + { + v128 equalValues = Sse2.cmpeq_epi16(a, b); + + if (promiseNeitherNaN) + { + if (promiseNeitherZero) + { + return equalValues; + } + else + { + v128 neitherZero = Sse2.cmpeq_epi16(Sse2.setzero_si128(), Sse2.slli_epi16(Sse2.or_si128(a, b), 1)); + + return Sse2.or_si128(neitherZero, equalValues); + } + } + else + { + v128 eitherNaN = cmpunord_ph(a, b, elements); + + if (promiseNeitherZero) + { + return Sse2.andnot_si128(eitherNaN, equalValues); + } + else + { + v128 neitherZero = Sse2.cmpeq_epi16(Sse2.setzero_si128(), Sse2.slli_epi16(Sse2.or_si128(a, b), 1)); + + return ternarylogic_si128(eitherNaN, neitherZero, equalValues, TernaryOperation.OxOE); + } + } + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpneq_ph(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_EQ_EPU16(a, 0, elements) || constexpr.ALL_EQ_EPU16(a, 0x8000, elements)) + { + if (promiseNeitherNaN) + { + return not_si128(Sse2.cmpeq_epi16(Sse2.slli_epi16(b, 1), Sse2.setzero_si128())); + } + else + { + return Sse2.andnot_si128(Sse2.cmpeq_epi16(Sse2.slli_epi16(b, 1), Sse2.setzero_si128()), cmpord_ph(b, b)); + } + } + else if (Xse.constexpr.ALL_EQ_EPU16(b, 0, elements) || Xse.constexpr.ALL_EQ_EPU16(b, 0x8000, elements)) + { + if (promiseNeitherNaN) + { + return not_si128(Sse2.cmpeq_epi16(Sse2.slli_epi16(a, 1), Sse2.setzero_si128())); + } + else + { + return Sse2.andnot_si128(Sse2.cmpeq_epi16(Sse2.slli_epi16(a, 1), Sse2.setzero_si128()), cmpord_ph(a, a)); + } + } + else + { + v128 equalValues = Sse2.cmpeq_epi16(a, b); + + if (promiseNeitherNaN) + { + if (promiseNeitherZero) + { + return not_si128(equalValues); + } + else + { + v128 bothZero = Sse2.cmpeq_epi16(Sse2.setzero_si128(), Sse2.slli_epi16(Sse2.or_si128(a, b), 1)); + + return nor_si128(bothZero, equalValues); + } + } + else + { + v128 eitherNaN = cmpunord_ph(a, b, elements); + + if (promiseNeitherZero) + { + return ornot_si128(equalValues, eitherNaN); + } + else + { + v128 bothZero = Sse2.cmpeq_epi16(Sse2.setzero_si128(), Sse2.slli_epi16(Sse2.or_si128(a, b), 1)); + + return ternarylogic_si128(eitherNaN, bothZero, equalValues, TernaryOperation.OxF1); + } + } + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmplt_ph(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_EQ_EPU16(b, 0, elements) || constexpr.ALL_EQ_EPU16(b, 0x8000, elements)) + { + v128 negative = Sse2.cmpgt_epi16(Sse2.setzero_si128(), a); + v128 zero = Sse2.cmpeq_epi16(Sse2.setzero_si128(), Sse2.slli_epi16(a, 1)); + + if (promiseNeitherNaN) + { + return Sse2.andnot_si128(zero, negative); + } + else + { + return ternarylogic_si128(cmpunord_ph(a, a), zero, negative, TernaryOperation.OxO2); + } + } + if (constexpr.ALL_EQ_EPU16(a, 0, elements) || constexpr.ALL_EQ_EPU16(a, 0x8000, elements)) + { + v128 positive = Sse2.cmpgt_epi16(b, Sse2.setzero_si128()); + v128 zero = Sse2.cmpeq_epi16(Sse2.setzero_si128(), Sse2.slli_epi16(b, 1)); + + if (promiseNeitherNaN) + { + return Sse2.andnot_si128(zero, positive); + } + else + { + return ternarylogic_si128(cmpunord_ph(b, b), zero, positive, TernaryOperation.OxO2); + } + } + + + v128 equalValues = Sse2.cmpeq_epi16(a, b); + + v128 signA = Sse2.srai_epi16(a, 15); + v128 signB = Sse2.srai_epi16(b, 15); + v128 equalSigns = Sse2.cmpeq_epi16(signA, signB); + v128 ifEqualSigns; + //if (Avx512.IsAvx512Supported) + //{ + // ifEqualSigns = ternarylogic_si128(equalValues, signA, cmple_epu16(b, a, elements), TernaryOperation.OxO9); + //} + //else + //{ + ifEqualSigns = ternarylogic_si128(equalValues, signA, cmpgt_epu16(b, a, elements), TernaryOperation.OxO6); + //} + + v128 orderedCmp; + if (promiseNeitherZero) + { + orderedCmp = blendv_si128(signA, ifEqualSigns, equalSigns); + } + else + { + v128 bothZero = Sse2.cmpeq_epi16(Sse2.setzero_si128(), Sse2.slli_epi16(Sse2.or_si128(a, b), 1)); + v128 ifOppositeSigns = Sse2.andnot_si128(bothZero, signA); + orderedCmp = blendv_si128(ifOppositeSigns, ifEqualSigns, equalSigns); + } + + if (promiseNeitherNaN) + { + return orderedCmp; + } + else + { + v128 eitherNaN = cmpunord_ph(a, b, elements); + + return Sse2.andnot_si128(eitherNaN, orderedCmp); + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpgt_ph(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + return cmplt_ph(b, a, promiseNeitherNaN, promiseNeitherZero, elements); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmple_ph(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_EQ_EPU16(b, 0, elements) || constexpr.ALL_EQ_EPU16(b, 0x8000, elements)) + { + v128 intLEzero = Sse2.cmpgt_epi16(Sse2.set1_epi16(1), a); + + if (promiseNeitherNaN) + { + return intLEzero; + } + else + { + return Sse2.andnot_si128(cmpunord_ph(a, a), intLEzero); + } + } + if (constexpr.ALL_EQ_EPU16(a, 0, elements) || constexpr.ALL_EQ_EPU16(a, 0x8000, elements)) + { + v128 uintGEzero = Sse2.cmpgt_epi16(b, Sse2.setzero_si128()); + v128 negativeZero = Sse2.cmpeq_epi16(b, Sse2.set1_epi16(unchecked((short)(1 << 15)))); + + if (promiseNeitherNaN) + { + return Sse2.or_si128(uintGEzero, negativeZero); + } + else + { + return ternarylogic_si128(cmpunord_ph(b, b), uintGEzero, negativeZero, TernaryOperation.OxOE); + } + } + + + v128 equalValues = Sse2.cmpeq_epi16(a, b); + + v128 signA = Sse2.srai_epi16(a, 15); + v128 signB = Sse2.srai_epi16(b, 15); + v128 equalSigns = Sse2.cmpeq_epi16(signA, signB); + v128 ifEqualSigns; + //if (Avx512.IsAvx512Supported) + //{ + // ifEqualSigns = ternarylogic_si128(equalValues, signA, cmple_epu16(b, a, elements), TernaryOperation.OxF9); + //} + //else + //{ + ifEqualSigns = ternarylogic_si128(equalValues, signA, cmpgt_epu16(b, a, elements), TernaryOperation.OxF6); + //} + + v128 orderedCmp; + if (promiseNeitherZero) + { + orderedCmp = blendv_si128(setall_si128(), ifEqualSigns, equalSigns); + } + else + { + v128 bothZero = Sse2.cmpeq_epi16(Sse2.setzero_si128(), Sse2.slli_epi16(Sse2.or_si128(a, b), 1)); + v128 ifOppositeSigns = Sse2.or_si128(bothZero, signA); + orderedCmp = blendv_si128(ifOppositeSigns, ifEqualSigns, equalSigns); + } + + if (promiseNeitherNaN) + { + return orderedCmp; + } + else + { + v128 eitherNaN = cmpunord_ph(a, b, elements); + + return Sse2.andnot_si128(eitherNaN, orderedCmp); + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpge_ph(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + return cmple_ph(b, a, promiseNeitherNaN, promiseNeitherZero, elements); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpngt_ph(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + return cmple_ph(b, a, promiseNeitherNaN, promiseNeitherZero, elements); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpnlt_ph(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + return cmpge_ph(b, a, promiseNeitherNaN, promiseNeitherZero, elements); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpnge_ph(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + return cmplt_ph(b, a, promiseNeitherNaN, promiseNeitherZero, elements); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpnle_ph(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 8) + { + if (Sse2.IsSse2Supported) + { + return cmpgt_ph(b, a, promiseNeitherNaN, promiseNeitherZero, elements); + } + else throw new IllegalInstructionException(); + } + } +} diff --git a/Runtime/XSE Core/Basic Mathematical Operations/Comparison/Float16.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/Float16.cs.meta new file mode 100644 index 0000000..bad5cd2 --- /dev/null +++ b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/Float16.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cf9ded1132d545049ba7a6d263e803d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/XSE Core/Basic Operations/Comparison/Greater-Equal.cs b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/Greater-Equal.cs similarity index 100% rename from Runtime/XSE Core/Basic Operations/Comparison/Greater-Equal.cs rename to Runtime/XSE Core/Basic Mathematical Operations/Comparison/Greater-Equal.cs diff --git a/Runtime/XSE Core/Basic Operations/Comparison/Greater-Equal.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/Greater-Equal.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Comparison/Greater-Equal.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Comparison/Greater-Equal.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/Comparison/Less-Equal.cs b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/Less-Equal.cs similarity index 100% rename from Runtime/XSE Core/Basic Operations/Comparison/Less-Equal.cs rename to Runtime/XSE Core/Basic Mathematical Operations/Comparison/Less-Equal.cs diff --git a/Runtime/XSE Core/Basic Operations/Comparison/Less-Equal.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/Less-Equal.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Comparison/Less-Equal.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Comparison/Less-Equal.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/Comparison/Less-Than Wrappers.cs b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/Less-Than Wrappers.cs similarity index 98% rename from Runtime/XSE Core/Basic Operations/Comparison/Less-Than Wrappers.cs rename to Runtime/XSE Core/Basic Mathematical Operations/Comparison/Less-Than Wrappers.cs index 62af544..6db8a91 100644 --- a/Runtime/XSE Core/Basic Operations/Comparison/Less-Than Wrappers.cs +++ b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/Less-Than Wrappers.cs @@ -51,9 +51,9 @@ public static v128 cmplt_epu64(v128 left, v128 right) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v256 mm256_cmplt_epu64(v256 left, v256 right) + public static v256 mm256_cmplt_epu64(v256 left, v256 right, byte elements = 4) { - return mm256_cmpgt_epu64(right, left); + return mm256_cmpgt_epu64(right, left, elements); } diff --git a/Runtime/XSE Core/Basic Operations/Comparison/Less-Than Wrappers.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/Less-Than Wrappers.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Comparison/Less-Than Wrappers.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Comparison/Less-Than Wrappers.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/Comparison/Unsigned Greater-Than.cs b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/Unsigned Greater-Than.cs similarity index 100% rename from Runtime/XSE Core/Basic Operations/Comparison/Unsigned Greater-Than.cs rename to Runtime/XSE Core/Basic Mathematical Operations/Comparison/Unsigned Greater-Than.cs diff --git a/Runtime/XSE Core/Basic Operations/Comparison/Unsigned Greater-Than.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/Unsigned Greater-Than.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Comparison/Unsigned Greater-Than.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Comparison/Unsigned Greater-Than.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/Comparison/v256 Greater-Than 64 Wrapper.cs b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/v256 Greater-Than 64 Wrapper.cs similarity index 100% rename from Runtime/XSE Core/Basic Operations/Comparison/v256 Greater-Than 64 Wrapper.cs rename to Runtime/XSE Core/Basic Mathematical Operations/Comparison/v256 Greater-Than 64 Wrapper.cs diff --git a/Runtime/XSE Core/Basic Operations/Comparison/v256 Greater-Than 64 Wrapper.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Comparison/v256 Greater-Than 64 Wrapper.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Comparison/v256 Greater-Than 64 Wrapper.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Comparison/v256 Greater-Than 64 Wrapper.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/FMA.meta b/Runtime/XSE Core/Basic Mathematical Operations/FMA.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/FMA.meta rename to Runtime/XSE Core/Basic Mathematical Operations/FMA.meta diff --git a/Runtime/XSE Core/Basic Operations/FMA/Double FMA Wrappers.cs b/Runtime/XSE Core/Basic Mathematical Operations/FMA/Double FMA Wrappers.cs similarity index 99% rename from Runtime/XSE Core/Basic Operations/FMA/Double FMA Wrappers.cs rename to Runtime/XSE Core/Basic Mathematical Operations/FMA/Double FMA Wrappers.cs index ded0153..340800f 100644 --- a/Runtime/XSE Core/Basic Operations/FMA/Double FMA Wrappers.cs +++ b/Runtime/XSE Core/Basic Mathematical Operations/FMA/Double FMA Wrappers.cs @@ -1,4 +1,4 @@ -#define TESTING +//#define TESTING using System.Runtime.CompilerServices; diff --git a/Runtime/XSE Core/Basic Operations/FMA/Double FMA Wrappers.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/FMA/Double FMA Wrappers.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/FMA/Double FMA Wrappers.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/FMA/Double FMA Wrappers.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/FMA/Float FMA Wrappers.cs b/Runtime/XSE Core/Basic Mathematical Operations/FMA/Float FMA Wrappers.cs similarity index 100% rename from Runtime/XSE Core/Basic Operations/FMA/Float FMA Wrappers.cs rename to Runtime/XSE Core/Basic Mathematical Operations/FMA/Float FMA Wrappers.cs diff --git a/Runtime/XSE Core/Basic Operations/FMA/Float FMA Wrappers.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/FMA/Float FMA Wrappers.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/FMA/Float FMA Wrappers.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/FMA/Float FMA Wrappers.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/FMA/Float Fused Divide.cs b/Runtime/XSE Core/Basic Mathematical Operations/FMA/Float Fused Divide.cs similarity index 100% rename from Runtime/XSE Core/Basic Operations/FMA/Float Fused Divide.cs rename to Runtime/XSE Core/Basic Mathematical Operations/FMA/Float Fused Divide.cs diff --git a/Runtime/XSE Core/Basic Operations/FMA/Float Fused Divide.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/FMA/Float Fused Divide.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/FMA/Float Fused Divide.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/FMA/Float Fused Divide.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/FMA/Float Fused Inverse Square Root.cs b/Runtime/XSE Core/Basic Mathematical Operations/FMA/Float Fused Inverse Square Root.cs similarity index 100% rename from Runtime/XSE Core/Basic Operations/FMA/Float Fused Inverse Square Root.cs rename to Runtime/XSE Core/Basic Mathematical Operations/FMA/Float Fused Inverse Square Root.cs diff --git a/Runtime/XSE Core/Basic Operations/FMA/Float Fused Inverse Square Root.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/FMA/Float Fused Inverse Square Root.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/FMA/Float Fused Inverse Square Root.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/FMA/Float Fused Inverse Square Root.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/Increment Decrement.cs b/Runtime/XSE Core/Basic Mathematical Operations/Increment Decrement.cs similarity index 70% rename from Runtime/XSE Core/Basic Operations/Increment Decrement.cs rename to Runtime/XSE Core/Basic Mathematical Operations/Increment Decrement.cs index 2913432..b691371 100644 --- a/Runtime/XSE Core/Basic Operations/Increment Decrement.cs +++ b/Runtime/XSE Core/Basic Mathematical Operations/Increment Decrement.cs @@ -32,7 +32,7 @@ public static v128 incs_epu8(v128 a) { if (Sse2.IsSse2Supported) { - return Sse2.subs_epu8(a, setall_si128()); + return Sse2.adds_epu8(a, Sse2.set1_epi8(1)); } else throw new IllegalInstructionException(); } @@ -62,7 +62,7 @@ public static v128 incs_epu16(v128 a) { if (Sse2.IsSse2Supported) { - return Sse2.subs_epu16(a, setall_si128()); + return Sse2.adds_epu16(a, Sse2.set1_epi16(1)); } else throw new IllegalInstructionException(); } @@ -78,21 +78,35 @@ public static v128 inc_epi32(v128 a) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v128 incs_epi32(v128 a) + public static v128 incs_epi32(v128 a, byte elements = 4) { if (Sse2.IsSse2Supported) { - return subs_epi32(a, setall_si128()); + if (constexpr.ALL_LT_EPI32(a, int.MaxValue, elements)) + { + return Sse2.sub_epi32(a, setall_si128()); + } + else + { + return subs_epi32(a, setall_si128(), elements); + } } else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v128 incs_epu32(v128 a) + public static v128 incs_epu32(v128 a, byte elements = 4) { if (Sse2.IsSse2Supported) { - return subs_epu32(a, setall_si128()); + if (constexpr.ALL_LT_EPU32(a, uint.MaxValue, elements)) + { + return Sse2.sub_epi32(a, setall_si128()); + } + else + { + return adds_epu32(a, Sse2.set1_epi32(1)); + } } else throw new IllegalInstructionException(); } @@ -112,7 +126,14 @@ public static v128 incs_epi64(v128 a) { if (Sse2.IsSse2Supported) { - return subs_epi64(a, setall_si128()); + if (constexpr.ALL_LT_EPI64(a, long.MaxValue)) + { + return Sse2.sub_epi64(a, setall_si128()); + } + else + { + return subs_epi64(a, setall_si128()); + } } else throw new IllegalInstructionException(); } @@ -122,7 +143,14 @@ public static v128 incs_epu64(v128 a) { if (Sse2.IsSse2Supported) { - return subs_epu64(a, setall_si128()); + if (constexpr.ALL_LT_EPU64(a, ulong.MaxValue)) + { + return Sse2.sub_epi64(a, setall_si128()); + } + else + { + return adds_epu64(a, Sse2.set1_epi64x(1)); + } } else throw new IllegalInstructionException(); } @@ -153,7 +181,7 @@ public static v256 mm256_incs_epu8(v256 a) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_subs_epu8(a, mm256_setall_si256()); + return Avx2.mm256_adds_epu8(a, Avx.mm256_set1_epi8(1)); } else throw new IllegalInstructionException(); } @@ -183,7 +211,7 @@ public static v256 mm256_incs_epu16(v256 a) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_subs_epu16(a, mm256_setall_si256()); + return Avx2.mm256_adds_epu16(a, Avx.mm256_set1_epi16(1)); } else throw new IllegalInstructionException(); } @@ -203,7 +231,14 @@ public static v256 mm256_incs_epi32(v256 a) { if (Avx2.IsAvx2Supported) { - return mm256_subs_epi32(a, mm256_setall_si256()); + if (constexpr.ALL_LT_EPI32(a, int.MaxValue)) + { + return Avx2.mm256_sub_epi32(a, mm256_setall_si256()); + } + else + { + return mm256_subs_epi32(a, mm256_setall_si256()); + } } else throw new IllegalInstructionException(); } @@ -213,7 +248,14 @@ public static v256 mm256_incs_epu32(v256 a) { if (Avx2.IsAvx2Supported) { - return mm256_subs_epu32(a, mm256_setall_si256()); + if (constexpr.ALL_LT_EPU32(a, uint.MaxValue)) + { + return Avx2.mm256_sub_epi32(a, mm256_setall_si256()); + } + else + { + return mm256_adds_epu32(a, Avx.mm256_set1_epi32(1)); + } } else throw new IllegalInstructionException(); } @@ -229,26 +271,40 @@ public static v256 mm256_inc_epi64(v256 a) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v256 mm256_incs_epi64(v256 a) + public static v256 mm256_incs_epi64(v256 a, byte elements = 4) { if (Avx2.IsAvx2Supported) { - return mm256_subs_epi64(a, mm256_setall_si256()); + if (constexpr.ALL_LT_EPI64(a, long.MaxValue, elements)) + { + return Avx2.mm256_sub_epi64(a, mm256_setall_si256()); + } + else + { + return mm256_subs_epi64(a, mm256_setall_si256()); + } } else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v256 mm256_incs_epu64(v256 a) + public static v256 mm256_incs_epu64(v256 a, byte elements = 4) { if (Avx2.IsAvx2Supported) { - return mm256_subs_epu64(a, mm256_setall_si256()); + if (constexpr.ALL_LT_EPU64(a, ulong.MaxValue, elements)) + { + return Avx2.mm256_sub_epi64(a, mm256_setall_si256()); + } + else + { + return mm256_adds_epu64(a, Avx.mm256_set1_epi64x(1), elements); + } } else throw new IllegalInstructionException(); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v128 dec_epi8(v128 a) { @@ -274,7 +330,7 @@ public static v128 decs_epu8(v128 a) { if (Sse2.IsSse2Supported) { - return Sse2.adds_epu8(a, setall_si128()); + return Sse2.subs_epu8(a, Sse2.set1_epi8(1)); } else throw new IllegalInstructionException(); } @@ -304,7 +360,7 @@ public static v128 decs_epu16(v128 a) { if (Sse2.IsSse2Supported) { - return Sse2.adds_epu16(a, setall_si128()); + return Sse2.subs_epu16(a, Sse2.set1_epi16(1)); } else throw new IllegalInstructionException(); } @@ -320,11 +376,18 @@ public static v128 dec_epi32(v128 a) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v128 decs_epi32(v128 a) + public static v128 decs_epi32(v128 a, byte elements = 4) { if (Sse2.IsSse2Supported) { - return adds_epi32(a, setall_si128()); + if (constexpr.ALL_GT_EPI32(a, int.MinValue, elements)) + { + return Sse2.add_epi32(a, setall_si128()); + } + else + { + return adds_epi32(a, setall_si128(), elements); + } } else throw new IllegalInstructionException(); } @@ -334,7 +397,14 @@ public static v128 decs_epu32(v128 a, byte elements = 4) { if (Sse2.IsSse2Supported) { - return adds_epu32(a, setall_si128(), elements); + if (constexpr.ALL_GT_EPU32(a, uint.MinValue, elements)) + { + return Sse2.add_epi32(a, setall_si128()); + } + else + { + return subs_epu32(a, Sse2.set1_epi32(1)); + } } else throw new IllegalInstructionException(); } @@ -354,7 +424,14 @@ public static v128 decs_epi64(v128 a) { if (Sse2.IsSse2Supported) { - return adds_epi64(a, setall_si128()); + if (constexpr.ALL_GT_EPI64(a, long.MinValue)) + { + return Sse2.add_epi64(a, setall_si128()); + } + else + { + return adds_epi64(a, setall_si128()); + } } else throw new IllegalInstructionException(); } @@ -364,7 +441,14 @@ public static v128 decs_epu64(v128 a) { if (Sse2.IsSse2Supported) { - return adds_epu64(a, setall_si128()); + if (constexpr.ALL_GT_EPU64(a, ulong.MinValue)) + { + return Sse2.add_epi64(a, setall_si128()); + } + else + { + return subs_epu64(a, Sse2.set1_epi64x(1)); + } } else throw new IllegalInstructionException(); } @@ -395,7 +479,7 @@ public static v256 mm256_decs_epu8(v256 a) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_adds_epu8(a, mm256_setall_si256()); + return Avx2.mm256_subs_epu8(a, Avx.mm256_set1_epi8(1)); } else throw new IllegalInstructionException(); } @@ -425,7 +509,7 @@ public static v256 mm256_decs_epu16(v256 a) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_adds_epu16(a, mm256_setall_si256()); + return Avx2.mm256_subs_epu16(a, Avx.mm256_set1_epi16(1)); } else throw new IllegalInstructionException(); } @@ -445,7 +529,14 @@ public static v256 mm256_decs_epi32(v256 a) { if (Avx2.IsAvx2Supported) { - return mm256_adds_epi32(a, mm256_setall_si256()); + if (constexpr.ALL_GT_EPI32(a, int.MinValue)) + { + return Avx2.mm256_add_epi32(a, mm256_setall_si256()); + } + else + { + return mm256_adds_epi32(a, mm256_setall_si256()); + } } else throw new IllegalInstructionException(); } @@ -455,7 +546,14 @@ public static v256 mm256_decs_epu32(v256 a) { if (Avx2.IsAvx2Supported) { - return mm256_adds_epu32(a, mm256_setall_si256()); + if (constexpr.ALL_GT_EPU32(a, uint.MinValue)) + { + return Avx2.mm256_add_epi32(a, mm256_setall_si256()); + } + else + { + return mm256_subs_epu32(a, Avx.mm256_set1_epi32(1)); + } } else throw new IllegalInstructionException(); } @@ -471,21 +569,35 @@ public static v256 mm256_dec_epi64(v256 a) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v256 mm256_decs_epi64(v256 a) + public static v256 mm256_decs_epi64(v256 a, byte elements = 4) { if (Avx2.IsAvx2Supported) { - return mm256_adds_epi64(a, mm256_setall_si256()); + if (constexpr.ALL_GT_EPI64(a, long.MinValue, elements)) + { + return Avx2.mm256_add_epi64(a, mm256_setall_si256()); + } + else + { + return mm256_adds_epi64(a, mm256_setall_si256()); + } } else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v256 mm256_decs_epu64(v256 a) + public static v256 mm256_decs_epu64(v256 a, byte elements = 4) { if (Avx2.IsAvx2Supported) { - return mm256_adds_epu64(a, mm256_setall_si256()); + if (constexpr.ALL_GT_EPU64(a, ulong.MinValue, elements)) + { + return Avx2.mm256_add_epi64(a, mm256_setall_si256()); + } + else + { + return mm256_subs_epu64(a, Avx.mm256_set1_epi64x(1), elements); + } } else throw new IllegalInstructionException(); } diff --git a/Runtime/XSE Core/Basic Operations/Increment Decrement.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Increment Decrement.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Increment Decrement.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Increment Decrement.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/Integer Division.meta b/Runtime/XSE Core/Basic Mathematical Operations/Integer Division.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Integer Division.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Integer Division.meta diff --git a/Runtime/XSE Core/Basic Operations/Integer Division/By Vector.meta b/Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Integer Division/By Vector.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector.meta diff --git a/Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/16bit Range Via Float Conversion.cs b/Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/16bit Range Via Float Conversion.cs new file mode 100644 index 0000000..f20c18f --- /dev/null +++ b/Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/16bit Range Via Float Conversion.cs @@ -0,0 +1,54 @@ +using System.Runtime.CompilerServices; +using Unity.Burst.Intrinsics; + +using static Unity.Burst.Intrinsics.X86; + +namespace MaxMath.Intrinsics +{ + unsafe public static partial class Xse + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v128 DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(v128 dividend_f32, v128 divisor_f32) + { + if (Sse2.IsSse2Supported) + { + //if (BurstCompiler.FloatMode == FloatMode.Fast) + //{ + // v128 divisorRcp = Sse.rcp_ps(divisor_f32); + // v128 approxQuotient = Sse.mul_ps(dividend_f32, divisorRcp); + // v128 precisionLossCompensation = fnmadd_ps(divisorRcp, divisor_f32, Sse2.set1_epi32(0x4000_0002)); + // + // return Sse2.cvttps_epi32(Sse.mul_ps(precisionLossCompensation, approxQuotient)); + //} + //else + //{ + // actually faster on newer CPUs than reciprocal multiplication + return Sse2.cvttps_epi32(Sse.div_ps(dividend_f32, divisor_f32)); + //} + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static v256 DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(v256 dividend_f32, v256 divisor_f32) + { + if (Avx.IsAvxSupported) + { + //if (BurstCompiler.FloatMode == FloatMode.Fast) + //{ + // v256 divisorRcp = Avx.mm256_rcp_ps(divisor_f32); + // v256 approxQuotient = Avx.mm256_mul_ps(dividend_f32, divisorRcp); + // v256 precisionLossCompensation = mm256_fnmadd_ps(divisorRcp, divisor_f32, Avx.mm256_set1_epi32(0x4000_0002)); + // + // return Avx.mm256_cvttps_epi32(Avx.mm256_mul_ps(precisionLossCompensation, approxQuotient)); + //} + //else + //{ + // actually faster on newer CPUs than reciprocal multiplication + return Avx.mm256_cvttps_epi32(Avx.mm256_div_ps(dividend_f32, divisor_f32)); + //} + } + else throw new IllegalInstructionException(); + } + } +} \ No newline at end of file diff --git a/Runtime/XSE Core/Basic Operations/Integer Division/By Vector/16bit Range Via Float Conversion.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/16bit Range Via Float Conversion.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Integer Division/By Vector/16bit Range Via Float Conversion.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/16bit Range Via Float Conversion.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/Integer Division/By Vector/32bit Range Via Float Conversion.cs b/Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/32bit Range Via Float Conversion.cs similarity index 91% rename from Runtime/XSE Core/Basic Operations/Integer Division/By Vector/32bit Range Via Float Conversion.cs rename to Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/32bit Range Via Float Conversion.cs index d971483..7b7efa6 100644 --- a/Runtime/XSE Core/Basic Operations/Integer Division/By Vector/32bit Range Via Float Conversion.cs +++ b/Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/32bit Range Via Float Conversion.cs @@ -27,7 +27,7 @@ public static v128 div_epu32(v128 a, v128 b, byte elements = 4) } if (constexpr.ALL_LE_EPU32(a, ushort.MaxValue, elements) && constexpr.ALL_LE_EPU32(b, ushort.MaxValue, elements)) { - return Sse2.cvttps_epi32(DIV_FLOATV_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(a), Sse2.cvtepi32_ps(b))); + return Sse2.cvttps_epi32(DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(a), Sse2.cvtepi32_ps(b))); } if (constexpr.ALL_LE_EPU32(a, (uint)int.MaxValue) && constexpr.ALL_LE_EPU32(b, (uint)int.MaxValue)) { @@ -82,7 +82,7 @@ public static v256 mm256_div_epu32(v256 a, v256 b) } if (constexpr.ALL_LE_EPU32(a, ushort.MaxValue) && constexpr.ALL_LE_EPU32(b, ushort.MaxValue)) { - return Avx.mm256_cvttps_epi32(DIV_FLOATV_USHORT_RANGE_RET_INT(Avx.mm256_cvtepi32_ps(a), Avx.mm256_cvtepi32_ps(b))); + return Avx.mm256_cvttps_epi32(DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(Avx.mm256_cvtepi32_ps(a), Avx.mm256_cvtepi32_ps(b))); } if (constexpr.ALL_LE_EPU32(a, (uint)int.MaxValue) && constexpr.ALL_LE_EPU32(b, (uint)int.MaxValue)) { @@ -115,10 +115,10 @@ public static v128 div_epi32(v128 a, v128 b, byte elements = 4) { return constexpr.div_epi32(a, b, elements); } - if (constexpr.ALL_GE_EPI32(a, short.MinValue, elements) && constexpr.ALL_LE_EPI32(a, short.MaxValue, elements) && - constexpr.ALL_GE_EPI32(b, short.MinValue, elements) && constexpr.ALL_LE_EPI32(b, short.MaxValue, elements)) + if (constexpr.ALL_GE_EPI32(a, -ushort.MinValue, elements) && constexpr.ALL_LE_EPI32(a, ushort.MaxValue, elements) && + constexpr.ALL_GE_EPI32(b, -ushort.MaxValue, elements) && constexpr.ALL_LE_EPI32(b, ushort.MaxValue, elements)) { - return Sse2.cvttps_epi32(DIV_FLOATV_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(a), Sse2.cvtepi32_ps(b))); + return Sse2.cvttps_epi32(DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(a), Sse2.cvtepi32_ps(b))); } @@ -163,10 +163,10 @@ public static v256 mm256_div_epi32(v256 a, v256 b) { return constexpr.mm256_div_epi32(a, b); } - if (constexpr.ALL_GE_EPI32(a, short.MinValue) && constexpr.ALL_LE_EPI32(a, short.MaxValue) && - constexpr.ALL_GE_EPI32(b, short.MinValue) && constexpr.ALL_LE_EPI32(b, short.MaxValue)) + if (constexpr.ALL_GE_EPI32(a, -ushort.MinValue) && constexpr.ALL_LE_EPI32(a, ushort.MaxValue) && + constexpr.ALL_GE_EPI32(b, -ushort.MinValue) && constexpr.ALL_LE_EPI32(b, ushort.MaxValue)) { - return Avx.mm256_cvttps_epi32(DIV_FLOATV_USHORT_RANGE_RET_INT(Avx.mm256_cvtepi32_ps(a), Avx.mm256_cvtepi32_ps(b))); + return Avx.mm256_cvttps_epi32(DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(Avx.mm256_cvtepi32_ps(a), Avx.mm256_cvtepi32_ps(b))); } diff --git a/Runtime/XSE Core/Basic Operations/Integer Division/By Vector/32bit Range Via Float Conversion.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/32bit Range Via Float Conversion.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Integer Division/By Vector/32bit Range Via Float Conversion.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/32bit Range Via Float Conversion.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/Integer Division/By Vector/64bit Accelerated Bitwise Long Division.cs b/Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/64bit Using Double FPU.cs similarity index 55% rename from Runtime/XSE Core/Basic Operations/Integer Division/By Vector/64bit Accelerated Bitwise Long Division.cs rename to Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/64bit Using Double FPU.cs index fd13d25..69f7404 100644 --- a/Runtime/XSE Core/Basic Operations/Integer Division/By Vector/64bit Accelerated Bitwise Long Division.cs +++ b/Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/64bit Using Double FPU.cs @@ -8,6 +8,7 @@ namespace MaxMath.Intrinsics { + // David Monniaux, Alice Pain. Formally verified 32- and 64-bit integer division using double-precision floating-point arithmetic. 2022. hal-03722203￿ unsafe public static partial class Xse { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -17,7 +18,7 @@ public static v128 div_epu64(v128 a, v128 b) { Assert.AreNotEqual(b.ULong0, 0ul); Assert.AreNotEqual(b.ULong1, 0ul); - + if (Constant.IsConstantExpression(b)) { return constexpr.div_epu64(a, b); @@ -26,9 +27,11 @@ public static v128 div_epu64(v128 a, v128 b) { return usfcvttpd_epu64(Sse2.div_pd(usfcvtepu64_pd(a), usfcvtepu64_pd(b))); } - } - return new v128(a.ULong0 / b.ULong0, a.ULong1 / b.ULong1); + + return new v128(a.ULong0 / b.ULong0, a.ULong1 / b.ULong1); + } + else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -45,49 +48,37 @@ public static v256 mm256_div_epu64(v256 a, v256 b, byte elements = 4) if (Constant.IsConstantExpression(b)) { return constexpr.mm256_div_epu64(a, b, elements); + } if (constexpr.ALL_LE_EPU64(a, USF_CVT_EPU64_PD_LIMIT, elements) && constexpr.ALL_LE_EPU64(b, USF_CVT_EPU64_PD_LIMIT, elements)) { return mm256_usfcvttpd_epu64(Avx.mm256_div_pd(mm256_usfcvtepu64_pd(a), mm256_usfcvtepu64_pd(b))); } - - - if (elements == 3) - { - return new v256(a.ULong0 / b.ULong0, a.ULong1 / b.ULong1, a.ULong2 / b.ULong2, 0ul); - } - else - { - v256 ZERO = Avx.mm256_setzero_si256(); - v256 ONE = Avx.mm256_set1_epi64x(1); - - v256 shift = Avx2.mm256_sub_epi64(mm256_lzcnt_epi64(b), mm256_lzcnt_epi64(a)); - b = Avx2.mm256_sllv_epi64(b, shift); - v256 setZero = mm256_cmpgt_epu64(b, a); - a = Avx2.mm256_sub_epi64(a, Avx2.mm256_andnot_si256(setZero, b)); - v256 quotient = Avx2.mm256_andnot_si256(setZero, ONE); - - b = Avx2.mm256_srli_epi64(b, 1); - v256 foundResultMask = Avx2.mm256_cmpeq_epi64(shift, ZERO); - v256 result = Avx2.mm256_and_si256(quotient, foundResultMask); - shift = Avx2.mm256_sub_epi64(shift, ONE); - - while (mm256_notalltrue_epi256(mm256_cmpgt_epi64(ZERO, shift), 4)) - { - quotient = Avx2.mm256_slli_epi64(quotient, 1); - - setZero = mm256_cmpgt_epu64(b, a); - a = Avx2.mm256_sub_epi64(a, Avx2.mm256_andnot_si256(setZero, b)); - quotient = mm256_ternarylogic_si256(setZero, ONE, quotient, TernaryOperation.OxAE); - - b = Avx2.mm256_srli_epi64(b, 1); - foundResultMask = Avx2.mm256_cmpeq_epi64(shift, ZERO); - result = mm256_ternarylogic_si256(result, quotient, foundResultMask, TernaryOperation.OxF8); - shift = Avx2.mm256_sub_epi64(shift, ONE); - } + + + v256 rcpB = Avx.mm256_div_pd(Avx.mm256_set1_pd(1d), mm256_cvtepu64_pd(b, elements)); + v256 q1d = Avx.mm256_mul_pd(mm256_cvtepu64_pd(a, elements), rcpB); + + v256 q1 = mm256_cvtpd_epu64(q1d, elements, promise: true, evenOnTie: false); + v256 r1 = Avx2.mm256_sub_epi64(a, mm256_mullo_epi64(b, q1, elements)); + v256 r1d = mm256_cvtepi64_pd(r1, elements); + v256 q3d = Avx.mm256_mul_pd(r1d, rcpB); + + v256 q3 = mm256_cvtpd_epi64(q3d, elements, promise: true, evenOnTie: false); + v256 r3 = Avx2.mm256_sub_epi64(r1, mm256_mullo_epi64(b, q3, elements)); + v256 q2 = Avx2.mm256_add_epi64(q3, mm256_srai_epi64(r3, 63)); - return result; - } + v256 q = Avx2.mm256_add_epi64(q1, q2); + + v256 ONE = Avx.mm256_set1_epi64x(1); + v256 divBy1 = Avx2.mm256_cmpeq_epi64(b, ONE); + v256 qEither0or1 = Avx2.mm256_cmpgt_epi64(Avx.mm256_setzero_si256(), b); // <- code size optimization over lower latency (ILP). ZERO is used in mm256_mullo_epi64 (AVX2) + v256 specialResult = mm256_blendv_si256(a, Avx2.mm256_andnot_si256(mm256_cmplt_epu64(a, b, elements), ONE), qEither0or1); + v256 blendMSK = Avx2.mm256_or_si256(divBy1, qEither0or1); + + q = mm256_blendv_si256(q, specialResult, blendMSK); + + return q; } else throw new IllegalInstructionException(); } @@ -139,36 +130,7 @@ public static v256 mm256_rem_epu64(v256 a, v256 b, byte elements = 4) } - if (elements == 3) - { - return new v256(a.ULong0 % b.ULong0, a.ULong1 % b.ULong1, a.ULong2 % b.ULong2, 0ul); - } - else - { - v256 ZERO = Avx.mm256_setzero_si256(); - - v256 shift = Avx2.mm256_sub_epi64(mm256_lzcnt_epi64(b), mm256_lzcnt_epi64(a)); - b = Avx2.mm256_sllv_epi64(b, shift); - a = Avx2.mm256_sub_epi64(a, Avx2.mm256_andnot_si256(mm256_cmpgt_epu64(b, a), b)); - b = Avx2.mm256_srli_epi64(b, 1); - - shift = mm256_dec_epi64(shift); - v256 foundResultMask = mm256_cmpgt_epi64(ZERO, shift); - v256 result = Avx2.mm256_and_si256(a, foundResultMask); - - while (mm256_notalltrue_epi256(mm256_cmpgt_epi64(ZERO, shift), 4)) - { - a = Avx2.mm256_sub_epi64(a, Avx2.mm256_andnot_si256(mm256_cmpgt_epu64(b, a), b)); - b = Avx2.mm256_srli_epi64(b, 1); - - foundResultMask = Avx2.mm256_cmpeq_epi64(shift, ZERO); - result = mm256_ternarylogic_si256(result, a, foundResultMask, TernaryOperation.OxF8); - - shift = mm256_dec_epi64(shift); - } - - return result; - } + return Avx2.mm256_sub_epi64(a, mm256_mullo_epi64(mm256_div_epu64(a, b, elements), b, elements)); } else throw new IllegalInstructionException(); } @@ -189,7 +151,6 @@ public static v128 divrem_epu64(v128 a, v128 b, out v128 rem) } if (constexpr.ALL_LE_EPU64(a, USF_CVT_EPU64_PD_LIMIT) && constexpr.ALL_LE_EPU64(b, USF_CVT_EPU64_PD_LIMIT)) { - v128 quotient = usfcvttpd_epu64(Sse2.div_pd(usfcvtepu64_pd(a), usfcvtepu64_pd(b))); rem = Sse2.sub_epi64(a, mullo_epi64(quotient, b)); @@ -217,58 +178,11 @@ public static v256 mm256_divrem_epu64(v256 a, v256 b, out v256 rem, byte element rem = constexpr.mm256_rem_epu64(a, b, elements); return constexpr.mm256_div_epu64(a, b, elements); } - if (constexpr.ALL_LE_EPU64(a, USF_CVT_EPU64_PD_LIMIT, elements) && constexpr.ALL_LE_EPU64(b, USF_CVT_EPU64_PD_LIMIT, elements)) - { - v256 quotient = mm256_usfcvttpd_epu64(Avx.mm256_div_pd(mm256_usfcvtepu64_pd(a), mm256_usfcvtepu64_pd(b))); - rem = Avx2.mm256_sub_epi64(a, mm256_mullo_epi64(quotient, b, elements)); - return quotient; - } - - if (elements == 3) - { - rem = new v256(a.ULong0 % b.ULong0, a.ULong1 % b.ULong1, a.ULong2 % b.ULong2, 0ul); - return new v256(a.ULong0 / b.ULong0, a.ULong1 / b.ULong1, a.ULong2 / b.ULong2, 0ul); - } - else - { - v256 ZERO = Avx.mm256_setzero_si256(); - v256 ONE = Avx.mm256_set1_epi64x(1); - - v256 shift = Avx2.mm256_sub_epi64(mm256_lzcnt_epi64(b), mm256_lzcnt_epi64(a)); - b = Avx2.mm256_sllv_epi64(b, shift); - v256 setZero = mm256_cmpgt_epu64(b, a); - a = Avx2.mm256_sub_epi64(a, Avx2.mm256_andnot_si256(setZero, b)); - v256 quotient = Avx2.mm256_andnot_si256(setZero, ONE); - b = Avx2.mm256_srli_epi64(b, 1); - - v256 foundResultMask = Avx2.mm256_cmpeq_epi64(shift, ZERO); - v256 result = Avx2.mm256_and_si256(quotient, foundResultMask); - - shift = Avx2.mm256_sub_epi64(shift, ONE); - foundResultMask = mm256_cmpgt_epi64(ZERO, shift); - rem = Avx2.mm256_and_si256(a, foundResultMask); - - while (mm256_notalltrue_epi256(foundResultMask, 4)) - { - quotient = Avx2.mm256_slli_epi64(quotient, 1); - - setZero = mm256_cmpgt_epu64(b, a); - a = Avx2.mm256_sub_epi64(a, Avx2.mm256_andnot_si256(setZero, b)); - quotient = mm256_ternarylogic_si256(setZero, ONE, quotient, TernaryOperation.OxAE); - b = Avx2.mm256_srli_epi64(b, 1); - - foundResultMask = Avx2.mm256_cmpeq_epi64(shift, ZERO); - result = mm256_ternarylogic_si256(result, quotient, foundResultMask, TernaryOperation.OxF8); - rem = mm256_ternarylogic_si256(rem, a, foundResultMask, TernaryOperation.OxF8); - - shift = Avx2.mm256_sub_epi64(shift, ONE); - foundResultMask = mm256_cmpgt_epi64(ZERO, shift); - } - - return result; - } + v256 quotient = mm256_div_epu64(a, b); + rem = Avx2.mm256_sub_epi64(a, mm256_mullo_epi64(quotient, b, elements)); + return quotient; } else throw new IllegalInstructionException(); } @@ -316,24 +230,17 @@ public static v256 mm256_div_epi64(v256 a, v256 b, byte elements = 4) } - if (elements == 3) - { - return new v256(a.SLong0 / b.SLong0, a.SLong1 / b.SLong1, a.SLong2 / b.SLong2, 0L); - } - else - { - v256 ZERO = Avx.mm256_setzero_si256(); - - v256 leftNegative = mm256_cmpgt_epi64(ZERO, a); - v256 rightNegative = mm256_cmpgt_epi64(ZERO, b); - a = Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(a, leftNegative), leftNegative); - b = Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(b, rightNegative), rightNegative); - - v256 quotient = mm256_div_epu64(a, b, elements); - v256 mustNegate = Avx2.mm256_xor_si256(leftNegative, rightNegative); - - return Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(quotient, mustNegate), mustNegate); - } + v256 ZERO = Avx.mm256_setzero_si256(); + + v256 leftNegative = mm256_cmpgt_epi64(ZERO, a, elements); + v256 rightNegative = mm256_cmpgt_epi64(ZERO, b, elements); + v256 mustNegate = Avx2.mm256_xor_si256(leftNegative, rightNegative); + a = Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(a, leftNegative), leftNegative); + b = Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(b, rightNegative), rightNegative); + + v256 quotient = mm256_div_epu64(a, b, elements); + + return Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(quotient, mustNegate), mustNegate); } else throw new IllegalInstructionException(); } @@ -385,23 +292,16 @@ public static v256 mm256_rem_epi64(v256 a, v256 b, byte elements = 4) } - if (elements == 3) - { - return new v256(a.SLong0 % b.SLong0, a.SLong1 % b.SLong1, a.SLong2 % b.SLong2, 0L); - } - else - { - v256 ZERO = Avx.mm256_setzero_si256(); - - v256 leftNegative = mm256_cmpgt_epi64(ZERO, a); - v256 rightNegative = mm256_cmpgt_epi64(ZERO, b); - a = Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(a, leftNegative), leftNegative); - b = Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(b, rightNegative), rightNegative); - - v256 remainder = mm256_rem_epu64(a, b); - - return Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(remainder, leftNegative), leftNegative); - } + v256 ZERO = Avx.mm256_setzero_si256(); + + v256 leftNegative = mm256_cmpgt_epi64(ZERO, a, elements); + v256 rightNegative = mm256_cmpgt_epi64(ZERO, b, elements); + a = Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(a, leftNegative), leftNegative); + b = Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(b, rightNegative), rightNegative); + + v256 remainder = mm256_rem_epu64(a, b, elements); + + return Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(remainder, leftNegative), leftNegative); } else throw new IllegalInstructionException(); } @@ -422,7 +322,6 @@ public static v128 divrem_epi64(v128 a, v128 b, out v128 rem) } if (constexpr.ALL_GE_EPI64(a, -ABS_MASK_USF_CVT_EPI64_PD_LIMIT) && constexpr.ALL_LE_EPI64(a, ABS_MASK_USF_CVT_EPI64_PD_LIMIT) && constexpr.ALL_GE_EPI64(b, -ABS_MASK_USF_CVT_EPI64_PD_LIMIT) && constexpr.ALL_LE_EPI64(b, ABS_MASK_USF_CVT_EPI64_PD_LIMIT)) { - v128 quotient = usfcvttpd_epi64(Sse2.div_pd(usfcvtepi64_pd(a), usfcvtepi64_pd(b))); rem = Sse2.sub_epi64(a, mullo_epi64(quotient, b)); @@ -450,7 +349,7 @@ public static v256 mm256_divrem_epi64(v256 a, v256 b, out v256 rem, byte element rem = constexpr.mm256_rem_epi64(a, b, elements); return constexpr.mm256_div_epi64(a, b, elements); } - if (constexpr.ALL_GE_EPI64(a, -ABS_MASK_USF_CVT_EPI64_PD_LIMIT, elements) && constexpr.ALL_LE_EPI64(a, ABS_MASK_USF_CVT_EPI64_PD_LIMIT, elements) && constexpr.ALL_GE_EPI64(b, -ABS_MASK_USF_CVT_EPI64_PD_LIMIT, elements) && constexpr.ALL_LE_EPI64(b, ABS_MASK_USF_CVT_EPI64_PD_LIMIT, elements)) + if (constexpr.ALL_GE_EPI64(a, -ABS_MASK_USF_CVT_EPI64_PD_LIMIT) && constexpr.ALL_LE_EPI64(a, ABS_MASK_USF_CVT_EPI64_PD_LIMIT) && constexpr.ALL_GE_EPI64(b, -ABS_MASK_USF_CVT_EPI64_PD_LIMIT) && constexpr.ALL_LE_EPI64(b, ABS_MASK_USF_CVT_EPI64_PD_LIMIT)) { v256 quotient = mm256_usfcvttpd_epi64(Avx.mm256_div_pd(mm256_usfcvtepi64_pd(a), mm256_usfcvtepi64_pd(b))); rem = Avx2.mm256_sub_epi64(a, mm256_mullo_epi64(quotient, b, elements)); @@ -459,26 +358,18 @@ public static v256 mm256_divrem_epi64(v256 a, v256 b, out v256 rem, byte element } - if (elements == 3) - { - rem = new v256(a.SLong0 % b.SLong0, a.SLong1 % b.SLong1, a.SLong2 % b.SLong2, 0L); - return new v256(a.SLong0 / b.SLong0, a.SLong1 / b.SLong1, a.SLong2 / b.SLong2, 0L); - } - else - { - v256 ZERO = Avx.mm256_setzero_si256(); - - v256 leftNegative = mm256_cmpgt_epi64(ZERO, a); - v256 rightNegative = mm256_cmpgt_epi64(ZERO, b); - a = Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(a, leftNegative), leftNegative); - b = Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(b, rightNegative), rightNegative); - - v256 quotient = mm256_divrem_epu64(a, b, out v256 remainders); - rem = Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(remainders, leftNegative), leftNegative); - v256 mustNegate = Avx2.mm256_xor_si256(leftNegative, rightNegative); - - return Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(quotient, mustNegate), mustNegate); - } + v256 ZERO = Avx.mm256_setzero_si256(); + + v256 leftNegative = mm256_cmpgt_epi64(ZERO, a, elements); + v256 rightNegative = mm256_cmpgt_epi64(ZERO, b, elements); + v256 mustNegate = Avx2.mm256_xor_si256(leftNegative, rightNegative); + a = Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(a, leftNegative), leftNegative); + b = Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(b, rightNegative), rightNegative); + + v256 quotientU = mm256_divrem_epu64(a, b, out v256 remainders, elements); + rem = Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(remainders, leftNegative), leftNegative); + + return Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(quotientU, mustNegate), mustNegate); } else throw new IllegalInstructionException(); } diff --git a/Runtime/XSE Core/Basic Operations/Integer Division/By Vector/64bit Accelerated Bitwise Long Division.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/64bit Using Double FPU.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Integer Division/By Vector/64bit Accelerated Bitwise Long Division.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/64bit Using Double FPU.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/Integer Division/By Vector/8bit Bitwise Long Division.cs b/Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/8bit Bitwise Long Division.cs similarity index 100% rename from Runtime/XSE Core/Basic Operations/Integer Division/By Vector/8bit Bitwise Long Division.cs rename to Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/8bit Bitwise Long Division.cs diff --git a/Runtime/XSE Core/Basic Operations/Integer Division/By Vector/8bit Bitwise Long Division.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/8bit Bitwise Long Division.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Integer Division/By Vector/8bit Bitwise Long Division.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/8bit Bitwise Long Division.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/Integer Division/By Vector/Public Dispatchers.cs b/Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/Public Dispatchers.cs similarity index 87% rename from Runtime/XSE Core/Basic Operations/Integer Division/By Vector/Public Dispatchers.cs rename to Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/Public Dispatchers.cs index a7f7e7e..a7e4090 100644 --- a/Runtime/XSE Core/Basic Operations/Integer Division/By Vector/Public Dispatchers.cs +++ b/Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/Public Dispatchers.cs @@ -27,8 +27,8 @@ public static v128 div_epu8(v128 dividend, v128 divisor, byte elements = 16) { v128 leftLo = cvt2x2epu16_ps(cvtepu8_epi16(dividend), out v128 leftHi); v128 rightLo = cvt2x2epu16_ps(cvtepu8_epi16(divisor), out v128 rightHi); - v128 intsLo = DIV_FLOATV_USHORT_RANGE_RET_INT(leftLo, rightLo); - v128 intsHi = DIV_FLOATV_USHORT_RANGE_RET_INT(leftHi, rightHi); + v128 intsLo = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftLo, rightLo); + v128 intsHi = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftHi, rightHi); v128 shorts = Sse2.packs_epi32(intsLo, intsHi); @@ -36,7 +36,7 @@ public static v128 div_epu8(v128 dividend, v128 divisor, byte elements = 16) } else { - v128 ints = DIV_FLOATV_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(cvtepu8_epi32(dividend)), Sse2.cvtepi32_ps(cvtepu8_epi32(divisor))); + v128 ints = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(cvtepu8_ps(dividend), cvtepu8_ps(divisor)); if (Ssse3.IsSsse3Supported) { @@ -86,7 +86,7 @@ public static v128 div_epi8(v128 dividend, v128 divisor, bool saturated = false, { v256 left = Avx.mm256_cvtepi32_ps(Avx2.mm256_cvtepi8_epi32(dividend)); v256 right = Avx.mm256_cvtepi32_ps(Avx2.mm256_cvtepi8_epi32(divisor)); - v256 result32 = DIV_FLOATV_USHORT_RANGE_RET_INT(left, right); + v256 result32 = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(left, right); if (saturated) { @@ -104,8 +104,8 @@ public static v128 div_epi8(v128 dividend, v128 divisor, bool saturated = false, { v128 leftLo = cvt2x2epi16_ps(cvtepi8_epi16(dividend), out v128 leftHi); v128 rightLo = cvt2x2epi16_ps(cvtepi8_epi16(divisor), out v128 rightHi); - v128 intsLo = DIV_FLOATV_USHORT_RANGE_RET_INT(leftLo, rightLo); - v128 intsHi = DIV_FLOATV_USHORT_RANGE_RET_INT(leftHi, rightHi); + v128 intsLo = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftLo, rightLo); + v128 intsHi = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftHi, rightHi); v128 shorts = Sse2.packs_epi32(intsLo, intsHi); @@ -122,7 +122,7 @@ public static v128 div_epi8(v128 dividend, v128 divisor, bool saturated = false, } else { - v128 ints = DIV_FLOATV_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(cvtepi8_epi32(dividend)), Sse2.cvtepi32_ps(cvtepi8_epi32(divisor))); + v128 ints = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(cvtepi8_epi32(dividend)), Sse2.cvtepi32_ps(cvtepi8_epi32(divisor))); if (saturated) { @@ -206,8 +206,8 @@ public static v128 rem_epu8(v128 dividend, v128 divisor, byte elements = 16) v128 castDivisor = cvtepu8_epi16(divisor); v128 leftLo = cvt2x2epu16_ps(castDividend, out v128 leftHi); v128 rightLo = cvt2x2epu16_ps(castDivisor, out v128 rightHi); - v128 quotientsLo = DIV_FLOATV_USHORT_RANGE_RET_INT(leftLo, rightLo); - v128 quotientsHi = DIV_FLOATV_USHORT_RANGE_RET_INT(leftHi, rightHi); + v128 quotientsLo = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftLo, rightLo); + v128 quotientsHi = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftHi, rightHi); v128 quotients16 = Sse2.packs_epi32(quotientsLo, quotientsHi); v128 rem16 = Sse2.sub_epi16(castDividend, Sse2.mullo_epi16(castDivisor, quotients16)); @@ -220,7 +220,7 @@ public static v128 rem_epu8(v128 dividend, v128 divisor, byte elements = 16) { v128 castDividend = cvtepu8_epi32(dividend); v128 castDivisor = cvtepu8_epi32(divisor); - v128 quotients32 = DIV_FLOATV_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(castDividend), Sse2.cvtepi32_ps(castDivisor)); + v128 quotients32 = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(castDividend), Sse2.cvtepi32_ps(castDivisor)); v128 rem32 = Sse2.sub_epi32(castDividend, Sse4_1.mullo_epi32(castDivisor, quotients32)); return cvtepi32_epi8(rem32, elements); @@ -229,7 +229,7 @@ public static v128 rem_epu8(v128 dividend, v128 divisor, byte elements = 16) { v128 castDividend = cvtepu8_epi16(dividend); v128 castDivisor = cvtepu8_epi16(divisor); - v128 quotients32 = DIV_FLOATV_USHORT_RANGE_RET_INT(cvtepu16_ps(castDividend), cvtepu16_ps(castDivisor)); + v128 quotients32 = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(cvtepu16_ps(castDividend), cvtepu16_ps(castDivisor)); v128 quotients16 = Sse2.packs_epi32(quotients32, quotients32); v128 rem16 = Sse2.sub_epi16(castDividend, Sse2.mullo_epi16(castDivisor, quotients16)); @@ -261,8 +261,8 @@ public static v128 rem_epi8(v128 dividend, v128 divisor, byte elements = 16) v128 castDivisor = cvtepi8_epi16(divisor); v128 leftLo = cvt2x2epi16_ps(castDividend, out v128 leftHi); v128 rightLo = cvt2x2epi16_ps(castDivisor, out v128 rightHi); - v128 quotientsLo = DIV_FLOATV_USHORT_RANGE_RET_INT(leftLo, rightLo); - v128 quotientsHi = DIV_FLOATV_USHORT_RANGE_RET_INT(leftHi, rightHi); + v128 quotientsLo = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftLo, rightLo); + v128 quotientsHi = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftHi, rightHi); v128 quotients16 = Sse2.packs_epi32(quotientsLo, quotientsHi); v128 rem16 = Sse2.sub_epi16(castDividend, Sse2.mullo_epi16(castDivisor, quotients16)); @@ -275,7 +275,7 @@ public static v128 rem_epi8(v128 dividend, v128 divisor, byte elements = 16) { v128 castDividend = cvtepi8_epi32(dividend); v128 castDivisor = cvtepi8_epi32(divisor); - v128 quotients32 = DIV_FLOATV_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(castDividend), Sse2.cvtepi32_ps(castDivisor)); + v128 quotients32 = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(castDividend), Sse2.cvtepi32_ps(castDivisor)); v128 rem32 = Sse2.sub_epi32(castDividend, Sse4_1.mullo_epi32(castDivisor, quotients32)); return cvtepi32_epi8(rem32, elements); @@ -284,7 +284,7 @@ public static v128 rem_epi8(v128 dividend, v128 divisor, byte elements = 16) { v128 castDividend = cvtepi8_epi16(dividend); v128 castDivisor = cvtepi8_epi16(divisor); - v128 quotients32 = DIV_FLOATV_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(cvtepi16_epi32(castDividend)), Sse2.cvtepi32_ps(cvtepi16_epi32(castDivisor))); + v128 quotients32 = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(cvtepi16_epi32(castDividend)), Sse2.cvtepi32_ps(cvtepi16_epi32(castDivisor))); v128 quotients16 = Sse2.packs_epi32(quotients32, quotients32); v128 rem16 = Sse2.sub_epi16(castDividend, Sse2.mullo_epi16(castDivisor, quotients16)); @@ -351,8 +351,8 @@ public static v128 divrem_epu8(v128 dividend, v128 divisor, out v128 remainder, v128 castDivisor = cvtepu8_epi16(divisor); v128 leftLo = cvt2x2epu16_ps(castDividend, out v128 leftHi); v128 rightLo = cvt2x2epu16_ps(castDivisor, out v128 rightHi); - v128 quotientsLo = DIV_FLOATV_USHORT_RANGE_RET_INT(leftLo, rightLo); - v128 quotientsHi = DIV_FLOATV_USHORT_RANGE_RET_INT(leftHi, rightHi); + v128 quotientsLo = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftLo, rightLo); + v128 quotientsHi = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftHi, rightHi); v128 quotients16 = Sse2.packs_epi32(quotientsLo, quotientsHi); remainder = Sse2.sub_epi16(castDividend, Sse2.mullo_epi16(castDivisor, quotients16)); @@ -366,7 +366,7 @@ public static v128 divrem_epu8(v128 dividend, v128 divisor, out v128 remainder, { v128 castDividend = cvtepu8_epi32(dividend); v128 castDivisor = cvtepu8_epi32(divisor); - v128 quotients32 = DIV_FLOATV_USHORT_RANGE_RET_INT(castDividend, castDivisor); + v128 quotients32 = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(castDividend, castDivisor); v128 rem32 = Sse2.sub_epi32(castDividend, Sse4_1.mullo_epi32(castDivisor, quotients32)); remainder = cvtepi32_epi8(quotients32); @@ -376,7 +376,7 @@ public static v128 divrem_epu8(v128 dividend, v128 divisor, out v128 remainder, { v128 castDividend = cvtepu8_epi16(dividend); v128 castDivisor = cvtepu8_epi16(divisor); - v128 quotients32 = DIV_FLOATV_USHORT_RANGE_RET_INT(cvtepu16_ps(castDividend), cvtepu16_ps(castDivisor)); + v128 quotients32 = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(cvtepu16_ps(castDividend), cvtepu16_ps(castDivisor)); v128 quotients16 = Sse2.packs_epi32(quotients32, quotients32); remainder = Sse2.sub_epi16(castDividend, Sse2.mullo_epi16(castDivisor, quotients16)); remainder = Sse2.packus_epi16(remainder, remainder); @@ -411,8 +411,8 @@ public static v128 divrem_epi8(v128 dividend, v128 divisor, out v128 remainder, v128 castDivisor = cvtepi8_epi16(divisor); v128 leftLo = cvt2x2epi16_ps(castDividend, out v128 leftHi); v128 rightLo = cvt2x2epi16_ps(castDivisor, out v128 rightHi); - v128 quotientsLo = DIV_FLOATV_USHORT_RANGE_RET_INT(leftLo, rightLo); - v128 quotientsHi = DIV_FLOATV_USHORT_RANGE_RET_INT(leftHi, rightHi); + v128 quotientsLo = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftLo, rightLo); + v128 quotientsHi = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftHi, rightHi); v128 quotients16 = Sse2.packs_epi32(quotientsLo, quotientsHi); remainder = Sse2.sub_epi16(castDividend, Sse2.mullo_epi16(castDivisor, quotients16)); @@ -426,7 +426,7 @@ public static v128 divrem_epi8(v128 dividend, v128 divisor, out v128 remainder, { v128 castDividend = cvtepi8_epi32(dividend); v128 castDivisor = cvtepi8_epi32(divisor); - v128 quotients32 = DIV_FLOATV_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(castDividend), Sse2.cvtepi32_ps(castDivisor)); + v128 quotients32 = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(castDividend), Sse2.cvtepi32_ps(castDivisor)); v128 rem32 = Sse2.sub_epi32(castDividend, Sse4_1.mullo_epi32(castDivisor, quotients32)); remainder = cvtepi32_epi8(rem32, elements); @@ -436,7 +436,7 @@ public static v128 divrem_epi8(v128 dividend, v128 divisor, out v128 remainder, { v128 castDividend = cvtepi8_epi16(dividend); v128 castDivisor = cvtepi8_epi16(divisor); - v128 quotients32 = DIV_FLOATV_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(cvtepi16_epi32(castDividend)), Sse2.cvtepi32_ps(cvtepi16_epi32(castDivisor))); + v128 quotients32 = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(cvtepi16_epi32(castDividend)), Sse2.cvtepi32_ps(cvtepi16_epi32(castDivisor))); v128 quotients16 = Sse2.packs_epi32(quotients32, quotients32); remainder = Sse2.sub_epi16(castDividend, Sse2.mullo_epi16(castDivisor, quotients16)); remainder = Sse2.packs_epi16(remainder, remainder); @@ -499,8 +499,8 @@ public static v128 div_epi16(v128 dividend, v128 divisor, bool saturated = false { v128 leftLo = cvt2x2epi16_ps(dividend, out v128 leftHi); v128 rightLo = cvt2x2epi16_ps(divisor, out v128 rightHi); - v128 intsLo = DIV_FLOATV_USHORT_RANGE_RET_INT(leftLo, rightLo); - v128 intsHi = DIV_FLOATV_USHORT_RANGE_RET_INT(leftHi, rightHi); + v128 intsLo = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftLo, rightLo); + v128 intsHi = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftHi, rightHi); if (saturated) { @@ -513,9 +513,9 @@ public static v128 div_epi16(v128 dividend, v128 divisor, bool saturated = false } else { - v128 ints = DIV_FLOATV_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(cvtepi16_epi32(dividend)), Sse2.cvtepi32_ps(cvtepi16_epi32(divisor))); - - if (saturated) + v128 ints = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(Sse2.cvtepi32_ps(cvtepi16_epi32(dividend)), Sse2.cvtepi32_ps(cvtepi16_epi32(divisor))); + + if (saturated || (constexpr.ALL_GT_EPI16(dividend, ushort.MinValue, elements) || constexpr.ALL_NEQ_EPI16(divisor, -1, elements))) { return Sse2.packs_epi32(ints, ints); } @@ -544,8 +544,8 @@ public static v128 div_epu16(v128 dividend, v128 divisor, byte elements = 8) v128 leftLo = cvt2x2epu16_ps(dividend, out v128 leftHi); v128 rightLo = cvt2x2epu16_ps(divisor, out v128 rightHi); - v128 qLo = DIV_FLOATV_USHORT_RANGE_RET_INT(leftLo, rightLo); - v128 qHi = DIV_FLOATV_USHORT_RANGE_RET_INT(leftHi, rightHi); + v128 qLo = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftLo, rightLo); + v128 qHi = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(leftHi, rightHi); if (Sse4_1.IsSse41Supported) { @@ -558,7 +558,7 @@ public static v128 div_epu16(v128 dividend, v128 divisor, byte elements = 8) } else { - v128 ints = DIV_FLOATV_USHORT_RANGE_RET_INT(cvtepu16_ps(dividend), cvtepu16_ps(divisor)); + v128 ints = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(cvtepu16_ps(dividend), cvtepu16_ps(divisor)); if (Sse4_1.IsSse41Supported) { @@ -587,10 +587,10 @@ public static v256 mm256_div_epi16(v256 dividend, v256 divisor, bool saturated = v256 dividendLo = mm256_cvt2x2epi16_ps(dividend, out v256 dividendHi); v256 divisorLo = mm256_cvt2x2epi16_ps(divisor, out v256 divisorHi); - v256 lo = DIV_FLOATV_USHORT_RANGE_RET_INT(dividendLo, divisorLo); - v256 hi = DIV_FLOATV_USHORT_RANGE_RET_INT(dividendHi, divisorHi); + v256 lo = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(dividendLo, divisorLo); + v256 hi = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(dividendHi, divisorHi); - if (saturated) + if (saturated || (constexpr.ALL_GT_EPI16(dividend, ushort.MinValue) || constexpr.ALL_NEQ_EPI16(divisor, -1))) { return Avx2.mm256_packs_epi32(lo, hi); } @@ -616,8 +616,8 @@ public static v256 mm256_div_epu16(v256 dividend, v256 divisor) v256 dividendLo = mm256_cvt2x2epu16_ps(dividend, out v256 dividendHi); v256 divisorLo = mm256_cvt2x2epu16_ps(divisor, out v256 divisorHi); - v256 lo = DIV_FLOATV_USHORT_RANGE_RET_INT(dividendLo, divisorLo); - v256 hi = DIV_FLOATV_USHORT_RANGE_RET_INT(dividendHi, divisorHi); + v256 lo = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(dividendLo, divisorLo); + v256 hi = DIV_FLOATV_SIGNED_USHORT_RANGE_RET_INT(dividendHi, divisorHi); return Avx2.mm256_packus_epi32(lo, hi); } diff --git a/Runtime/XSE Core/Basic Operations/Integer Division/By Vector/Public Dispatchers.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/Public Dispatchers.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Integer Division/By Vector/Public Dispatchers.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Integer Division/By Vector/Public Dispatchers.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/Integer Multiplication.cs b/Runtime/XSE Core/Basic Mathematical Operations/Integer Multiplication.cs similarity index 87% rename from Runtime/XSE Core/Basic Operations/Integer Multiplication.cs rename to Runtime/XSE Core/Basic Mathematical Operations/Integer Multiplication.cs index c24e99c..1cfec24 100644 --- a/Runtime/XSE Core/Basic Operations/Integer Multiplication.cs +++ b/Runtime/XSE Core/Basic Mathematical Operations/Integer Multiplication.cs @@ -69,7 +69,7 @@ public static v128 mulhi_epi8(v128 a, v128 b, byte elements = 16) even = Sse2.srli_epi16(even, 8); - return blendv_si128(even, odd, new v128(0xFF00_FF00)); + return blendv_si128(even, odd, Sse2.set1_epi16(unchecked((short)0xFF00))); } else throw new IllegalInstructionException(); } @@ -84,7 +84,7 @@ public static v256 mm256_mulhi_epi8(v256 a, v256 b) even = Avx2.mm256_srli_epi16(even, 8); - return mm256_blendv_si256(even, odd, new v256(0xFF00_FF00)); + return mm256_blendv_si256(even, odd, Avx.mm256_set1_epi16(unchecked((short)0xFF00))); } else throw new IllegalInstructionException(); } @@ -105,7 +105,7 @@ public static v128 mullo_epi8(v128 a, v128 b, byte elements = 16) v128 odd = Sse2.mullo_epi16(Sse2.srli_epi16(a, 8), Sse2.srli_epi16(b, 8)); odd = Sse2.slli_epi16(odd, 8); - return blendv_si128(even, odd, new v128(0xFF00_FF00)); + return blendv_si128(even, odd, Sse2.set1_epi16(unchecked((short)0xFF00))); } } else throw new IllegalInstructionException(); @@ -141,12 +141,22 @@ public static v128 mullo_epi32(v128 a, v128 b, byte elements = 4) } else { - v128 even = Sse2.mul_epu32(a, b); - v128 odd = Sse2.mul_epu32(Sse2.bsrli_si128(a, sizeof(int)), - Sse2.bsrli_si128(b, sizeof(int))); + if (elements == 2) + { + a = Sse2.shuffle_epi32(a, Sse.SHUFFLE(0, 1, 0, 0)); + b = Sse2.shuffle_epi32(b, Sse.SHUFFLE(0, 1, 0, 0)); + + return Sse2.shuffle_epi32(Sse2.mul_epu32(a, b), Sse.SHUFFLE(0, 0, 2, 0)); + } + else + { + v128 even = Sse2.mul_epu32(a, b); + v128 odd = Sse2.mul_epu32(Sse2.bsrli_si128(a, sizeof(int)), + Sse2.bsrli_si128(b, sizeof(int))); - return Sse2.unpacklo_epi64(Sse2.unpacklo_epi32(even, odd), - Sse2.unpackhi_epi32(even, odd)); + return Sse2.unpacklo_epi64(Sse2.unpacklo_epi32(even, odd), + Sse2.unpackhi_epi32(even, odd)); + } } } else throw new IllegalInstructionException(); @@ -298,7 +308,7 @@ public static v128 mulhi_epi64(v128 x, v128 y, out v128 low) { if (Sse2.IsSse2Supported) { - low = mulhi_epu64(x, y, out v128 high); + v128 high = mulhi_epu64(x, y, out low); if (constexpr.ALL_GE_EPI64(x, 0) && constexpr.ALL_GE_EPI64(y, 0)) { @@ -349,5 +359,26 @@ public static v256 mm256_mulhi_epu64(v256 x, v256 y, out v256 low, bool calcLow } else throw new IllegalInstructionException(); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_mulhi_epi64(v256 x, v256 y, out v256 low, byte elements = 4) + { + if (Avx2.IsAvx2Supported) + { + v256 high = mm256_mulhi_epu64(x, y, out low); + + if (constexpr.ALL_GE_EPI64(x, 0, elements) && constexpr.ALL_GE_EPI64(y, 0, elements)) + { + ; + } + else + { + high = Avx2.mm256_sub_epi64(high, Avx2.mm256_add_epi64(Avx2.mm256_and_si256(y, mm256_srai_epi64(x, 63)), Avx2.mm256_and_si256(x, mm256_srai_epi64(y, 63)))); + } + + return high; + } + else throw new IllegalInstructionException(); + } } } \ No newline at end of file diff --git a/Runtime/XSE Core/Basic Operations/Integer Multiplication.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Integer Multiplication.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Integer Multiplication.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Integer Multiplication.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/Negate.cs b/Runtime/XSE Core/Basic Mathematical Operations/Negate.cs similarity index 100% rename from Runtime/XSE Core/Basic Operations/Negate.cs rename to Runtime/XSE Core/Basic Mathematical Operations/Negate.cs diff --git a/Runtime/XSE Core/Basic Operations/Negate.cs.meta b/Runtime/XSE Core/Basic Mathematical Operations/Negate.cs.meta similarity index 100% rename from Runtime/XSE Core/Basic Operations/Negate.cs.meta rename to Runtime/XSE Core/Basic Mathematical Operations/Negate.cs.meta diff --git a/Runtime/XSE Core/Basic Operations/Integer Division/By Vector/16bit Range Via Float Conversion.cs b/Runtime/XSE Core/Basic Operations/Integer Division/By Vector/16bit Range Via Float Conversion.cs deleted file mode 100644 index f285c79..0000000 --- a/Runtime/XSE Core/Basic Operations/Integer Division/By Vector/16bit Range Via Float Conversion.cs +++ /dev/null @@ -1,169 +0,0 @@ -using System.Runtime.CompilerServices; -using Unity.Burst.Intrinsics; - -using static Unity.Burst.Intrinsics.X86; - -namespace MaxMath.Intrinsics -{ - unsafe public static partial class Xse - { - //// Let this test run for a few weeks LOL - I've validated the unambigious accuracy of division of every single (u)short value by every single (u)short value (except 0) - //// both with div_ps and mul_ps(rcp_ps, x) - by burst-compiling both functions and using varying float precision - // - //static void FullTest() - //{ - // NativeArray x = new NativeArray(1, Allocator.Persistent); - // NativeArray y = new NativeArray(1, Allocator.Persistent); - // - // JobHandle unsigned = new TestUnsignedJob { r = x }.Schedule(); - // JobHandle signed = new TestSignedJob { r = y }.Schedule(); - // - // JobHandle.ScheduleBatchedJobs(); - // - // unsigned.Complete(); - // signed.Complete(); - // - // print(x[0]); - // print(y[0]); - // - // x.Dispose(); - // y.Dispose(); - // - //} - // - //[BurstCompile(FloatMode = FloatMode.Fast, FloatPrecision = FloatPrecision.Low)] - //struct TestUnsignedJob : IJob - //{ - // internal NativeArray r; - // - // public void Execute() - // { - // bool result = true; - // - // ushort8 dividendStart = new ushort8(0, 1, 2, 3, 4, 5, 6, 7); - // - // for (int i = 1; i < ushort.MaxValue + 1; i += 8, dividendStart += 8) - // { - // ushort8 divisorStart = new ushort8(1, 2, 3, 4, 5, 6, 7, 8); - // - // for (int j = 1; j < 65529; j += 8, divisorStart += 8) - // { - // result &= div_epu16(dividendStart, divisorStart).Equals(new ushort8((ushort)(dividendStart.x0 / divisorStart.x0), - // (ushort)(dividendStart.x1 / divisorStart.x1), - // (ushort)(dividendStart.x2 / divisorStart.x2), - // (ushort)(dividendStart.x3 / divisorStart.x3), - // (ushort)(dividendStart.x4 / divisorStart.x4), - // (ushort)(dividendStart.x5 / divisorStart.x5), - // (ushort)(dividendStart.x6 / divisorStart.x6), - // (ushort)(dividendStart.x7 / divisorStart.x7))); - // } - // - // for (int j = 65529; j <= ushort.MaxValue; j++) - // { - // divisorStart = new ushort8((ushort)j); - // - // result &= div_epu16(dividendStart, divisorStart).Equals(new ushort8((ushort)(dividendStart.x0 / divisorStart.x0), - // (ushort)(dividendStart.x1 / divisorStart.x1), - // (ushort)(dividendStart.x2 / divisorStart.x2), - // (ushort)(dividendStart.x3 / divisorStart.x3), - // (ushort)(dividendStart.x4 / divisorStart.x4), - // (ushort)(dividendStart.x5 / divisorStart.x5), - // (ushort)(dividendStart.x6 / divisorStart.x6), - // (ushort)(dividendStart.x7 / divisorStart.x7))); - // } - // } - // - // r[0] = result; - // } - //} - // - //[BurstCompile(FloatMode = FloatMode.Fast, FloatPrecision = FloatPrecision.Low)] - //struct TestSignedJob : IJob - //{ - // internal NativeArray r; - // - // public void Execute() - // { - // bool result = true; - // - // short8 dividendStart = short.MinValue + new short8(0, 1, 2, 3, 4, 5, 6, 7); - // - // for (int i = 1; i < ushort.MaxValue + 1; i += 8, dividendStart += 8) - // { - // short8 divisorStart = short.MinValue + new short8(0, 1, 2, 3, 4, 5, 6, 7); - // - // for (int j = short.MinValue + 7; j < 0; j += 8, divisorStart += 8) - // { - // result &= div_epi16(dividendStart, divisorStart).Equals(new short8((short)(dividendStart.x0 / divisorStart.x0), - // (short)(dividendStart.x1 / divisorStart.x1), - // (short)(dividendStart.x2 / divisorStart.x2), - // (short)(dividendStart.x3 / divisorStart.x3), - // (short)(dividendStart.x4 / divisorStart.x4), - // (short)(dividendStart.x5 / divisorStart.x5), - // (short)(dividendStart.x6 / divisorStart.x6), - // (short)(dividendStart.x7 / divisorStart.x7))); - // } - // - // divisorStart = new short8(-8, -7, -6, -5, -4, -3, -2, -1); - // - // result &= div_epi16(dividendStart, divisorStart).Equals(new short8((short)(dividendStart.x0 / divisorStart.x0), - // (short)(dividendStart.x1 / divisorStart.x1), - // (short)(dividendStart.x2 / divisorStart.x2), - // (short)(dividendStart.x3 / divisorStart.x3), - // (short)(dividendStart.x4 / divisorStart.x4), - // (short)(dividendStart.x5 / divisorStart.x5), - // (short)(dividendStart.x6 / divisorStart.x6), - // (short)(dividendStart.x7 / divisorStart.x7))); - // - // divisorStart = new short8(1, 2, 3, 4, 5, 6, 7, 8); - // - // for (int j = 1; j < short.MaxValue + 1; j += 8, divisorStart += 8) - // { - // result &= div_epi16(dividendStart, divisorStart).Equals(new short8((short)(dividendStart.x0 / divisorStart.x0), - // (short)(dividendStart.x1 / divisorStart.x1), - // (short)(dividendStart.x2 / divisorStart.x2), - // (short)(dividendStart.x3 / divisorStart.x3), - // (short)(dividendStart.x4 / divisorStart.x4), - // (short)(dividendStart.x5 / divisorStart.x5), - // (short)(dividendStart.x6 / divisorStart.x6), - // (short)(dividendStart.x7 / divisorStart.x7))); - // } - // } - // - // r[0] = result; - // } - //} - - - private const int PRECISION_ADJUSTMENT = 0x4000_0002; - - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static v256 DIV_FLOATV_USHORT_RANGE_RET_INT(v256 dividend_f32, v256 divisor_f32) - { - if (Avx.IsAvxSupported) - { - v256 divisor_f32_rcp = Avx.mm256_rcp_ps(divisor_f32); - v256 rawQuotient = Avx.mm256_mul_ps(dividend_f32, divisor_f32_rcp); - v256 precisionLossCompensation = mm256_fnmadd_ps(divisor_f32_rcp, divisor_f32, Avx.mm256_set1_epi32(PRECISION_ADJUSTMENT)); - - return Avx.mm256_cvttps_epi32(Avx.mm256_mul_ps(precisionLossCompensation, rawQuotient)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static v128 DIV_FLOATV_USHORT_RANGE_RET_INT(v128 dividend_f32, v128 divisor_f32) - { - if (Sse2.IsSse2Supported) - { - v128 divisor_f32_rcp = Sse.rcp_ps(divisor_f32); - v128 rawQuotient = Sse.mul_ps(dividend_f32, divisor_f32_rcp); - v128 precisionLossCompensation = fnmadd_ps(divisor_f32_rcp, divisor_f32, Sse2.set1_epi32(PRECISION_ADJUSTMENT)); - - return Sse2.cvttps_epi32(Sse.mul_ps(precisionLossCompensation, rawQuotient)); - } - else throw new IllegalInstructionException(); - } - } -} \ No newline at end of file diff --git a/Runtime/XSE Core/Basic Operations/NOT.cs b/Runtime/XSE Core/Basic Operations/NOT.cs deleted file mode 100644 index db0a949..0000000 --- a/Runtime/XSE Core/Basic Operations/NOT.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Runtime.CompilerServices; -using Unity.Burst.Intrinsics; - -using static Unity.Burst.Intrinsics.X86; - -namespace MaxMath.Intrinsics -{ - unsafe public static partial class Xse - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v128 not_si128(v128 a) - { - if (Sse2.IsSse2Supported) - { - return ternarylogic_si128(a, a, a, TernaryOperation.OxOF); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v256 mm256_not_si256(v256 a) - { - if (Avx2.IsAvx2Supported) - { - return mm256_ternarylogic_si256(a, a, a, TernaryOperation.OxOF); - } - else throw new IllegalInstructionException(); - } - } -} diff --git a/Runtime/XSE Core/Cast/Float.cs b/Runtime/XSE Core/Cast/Float.cs index b848bcf..85a5bc0 100644 --- a/Runtime/XSE Core/Cast/Float.cs +++ b/Runtime/XSE Core/Cast/Float.cs @@ -1,9 +1,10 @@ +using System; using System.Runtime.CompilerServices; +using Unity.Mathematics; using Unity.Burst.Intrinsics; using static Unity.Burst.Intrinsics.X86; using static MaxMath.LUT.CVT_INT_FP; -using UnityEngine; namespace MaxMath.Intrinsics { @@ -35,7 +36,7 @@ public static v256 mm256_cvtepi64_pd(v256 x, byte elements = 4) } - v256 magic_lo = new v256(LIMIT_PRECISE_I32_F64); + v256 magic_lo = new v256(LIMIT_PRECISE_U64_F64); v256 magic_hi = new v256(0x4530_0000_8000_0000); v256 magic_dbl = new v256(0x4530_0000_8010_0000); @@ -77,7 +78,7 @@ public static v256 mm256_cvtepu64_pd(v256 x, byte elements = 4) } - v256 magic_lo = new v256(LIMIT_PRECISE_I32_F64); + v256 magic_lo = new v256(LIMIT_PRECISE_U64_F64); v256 magic_hi = new v256(0x4530_0000_0000_0000); v256 magic_dbl = new v256(0x4530_0000_0010_0000); @@ -93,6 +94,201 @@ public static v256 mm256_cvtepu64_pd(v256 x, byte elements = 4) } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cvtpd_epu64(v128 a, bool promise = false, bool evenOnTie = true) + { + if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_GE_PD(a, 0d) && constexpr.ALL_LE_PD(a, USF_CVT_EPU64_PD_LIMIT - 1d)) + { + return usfcvtpd_epu64(a); + } + else + { + v128 HALF = Sse2.set1_pd(0.5d); + + promise |= constexpr.ALL_GE_PD(a, 0d) && constexpr.ALL_LE_PD(a, long.MaxValue); + v128 truncatedResult = cvttpd_epi64(a); + + v128 fraction; + if (Sse4_1.IsSse41Supported) + { + fraction = Sse2.sub_pd(a, Sse4_1.round_pd(a, (int)RoundingMode.FROUND_TRUNC_NOEXC)); + } + else + { + fraction = Sse2.sub_pd(a, RegisterConversion.ToV128(math.trunc(RegisterConversion.ToDouble2(a)))); + } + + if (evenOnTie) + { + throw new NotImplementedException(); + } + else + { + // wrong on overflow? + if (promise) + { + v128 round = Sse2.cmpge_pd(fraction, HALF); + + return Sse2.sub_epi64(truncatedResult, round); + } + else + { + throw new NotImplementedException(); + } + } + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cvtpd_epi64(v128 x, bool promise = false, bool evenOnTie = true) + { + if (Sse2.IsSse2Supported) + { + if (constexpr.ALL_GE_PD(x, -ABS_MASK_USF_CVT_EPI64_PD_LIMIT + 1d) && constexpr.ALL_LE_PD(x, ABS_MASK_USF_CVT_EPI64_PD_LIMIT - 1d)) + { + return usfcvtpd_epi64(x); + } + else + { + v128 HALF = Sse2.set1_pd(0.5d); + v128 SIGN = Sse2.set1_epi64x(unchecked((long)(1ul << 63))); + + promise |= constexpr.ALL_GE_PD(x, long.MinValue) && constexpr.ALL_LE_PD(x, long.MaxValue); + v128 truncatedResult = cvttpd_epi64(x); + + v128 fraction; + if (Sse4_1.IsSse41Supported) + { + fraction = Sse2.sub_pd(x, Sse4_1.round_pd(x, (int)RoundingMode.FROUND_TRUNC_NOEXC)); + } + else + { + fraction = Sse2.sub_pd(x, RegisterConversion.ToV128(math.trunc(RegisterConversion.ToDouble2(x)))); + } + + + if (evenOnTie) + { + throw new NotImplementedException(); + } + else + { + if (promise) + { + v128 negativeMask = Sse2.cmpgt_pd(Sse.setzero_ps(), x); + + v128 cmp = ternarylogic_si128(HALF, negativeMask, SIGN, TernaryOperation.Ox78); + v128 cmpIfNegative = Sse2.cmple_pd(fraction, cmp); + v128 cmpIfPositive = Sse2.cmpge_pd(fraction, cmp); + + v128 round = blendv_si128(cmpIfPositive, cmpIfNegative, negativeMask); + round = Sse2.sub_epi64(Sse2.xor_si128(round, negativeMask), negativeMask); + + return Sse2.sub_epi64(truncatedResult, round); + } + else + { + throw new NotImplementedException(); + } + } + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_cvtpd_epi64(v256 a, byte elements = 4, bool promise = false, bool evenOnTie = true) + { + if (Avx2.IsAvx2Supported) + { + if (constexpr.ALL_GE_PD(a, -ABS_MASK_USF_CVT_EPI64_PD_LIMIT + 1d, elements) && constexpr.ALL_LE_PD(a, ABS_MASK_USF_CVT_EPI64_PD_LIMIT - 1d, elements)) + { + return mm256_usfcvtpd_epi64(a); + } + else + { + v256 HALF = Avx.mm256_set1_pd(0.5d); + v256 SIGN = Avx.mm256_set1_epi64x(unchecked((long)(1ul << 63))); + + promise |= constexpr.ALL_GE_PD(a, long.MinValue, elements) && constexpr.ALL_LE_PD(a, long.MaxValue, elements); + v256 truncatedResult = mm256_cvttpd_epi64_BASE(a, signed: true, elements, promise); + + v256 fraction = Avx.mm256_sub_pd(a, Avx.mm256_round_pd(a, (int)RoundingMode.FROUND_TRUNC)); + + if (evenOnTie) + { + throw new NotImplementedException(); + } + else + { + if (promise) + { + v256 negativeMask = Avx.mm256_cmp_pd(Avx.mm256_setzero_pd(), a, (int)Avx.CMP.GT_OQ); + + v256 cmp = mm256_ternarylogic_si256(HALF, negativeMask, SIGN, TernaryOperation.Ox78); + v256 cmpIfNegative = Avx.mm256_cmp_pd(fraction, cmp, (int)Avx.CMP.LE_OQ); + v256 cmpIfPositive = Avx.mm256_cmp_pd(fraction, cmp, (int)Avx.CMP.GE_OQ); + + v256 round = mm256_blendv_si256(cmpIfPositive, cmpIfNegative, negativeMask); + round = Avx2.mm256_sub_epi64(Avx2.mm256_xor_si256(round, negativeMask), negativeMask); + + return Avx2.mm256_sub_epi64(truncatedResult, round); + } + else + { + throw new NotImplementedException(); + } + } + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_cvtpd_epu64(v256 a, byte elements = 4, bool promise = false, bool evenOnTie = true) + { + if (Avx2.IsAvx2Supported) + { + if (constexpr.ALL_GE_PD(a, 0d, elements) && constexpr.ALL_LE_PD(a, USF_CVT_EPU64_PD_LIMIT - 1d, elements)) + { + return mm256_usfcvtpd_epu64(a); + } + else + { + v256 HALF = Avx.mm256_set1_pd(0.5d); + + promise |= constexpr.ALL_GE_PD(a, 0d, elements) && constexpr.ALL_LE_PD(a, long.MaxValue, elements); + v256 truncatedResult = mm256_cvttpd_epi64_BASE(a, signed: false, elements, promise); + + v256 fraction = Avx.mm256_sub_pd(a, Avx.mm256_round_pd(a, (int)RoundingMode.FROUND_TRUNC)); + + if (evenOnTie) + { + throw new NotImplementedException(); + } + else + { + // wrong on overflow? + if (promise) + { + v256 round = Avx.mm256_cmp_pd(fraction, HALF, (int)Avx.CMP.GE_OQ); + + return Avx2.mm256_sub_epi64(truncatedResult, round); + } + else + { + throw new NotImplementedException(); + } + } + } + } + else throw new IllegalInstructionException(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v128 cvttpd_epi64(v128 x) { @@ -179,14 +375,14 @@ private static v256 mm256_cvttpd_epi64_BASE(v256 a, bool signed, byte elements = const ulong BIAS = 0x03FFul; v256 ZERO = Avx.mm256_setzero_si256(); v256 ONE = Avx.mm256_set1_epi64x(1L); - v256 IMPL_ONE = Avx.mm256_set1_epi64x(1L << 52); + v256 IMPLICIT_ONE = Avx.mm256_set1_epi64x(1L << 52); v256 MANTISSA_MASK = Avx.mm256_set1_epi64x((1L << 52) - 1); v256 biased_exp = Avx2.mm256_srli_epi64(Avx2.mm256_slli_epi64(a, 1), 53); v256 shift_mnt = Avx2.mm256_subs_epu16(new v256(BIAS + 51), biased_exp); v256 shift_int = Avx2.mm256_subs_epu16(biased_exp, new v256(BIAS + 51)); - v256 mantissa = mm256_ternarylogic_si256(IMPL_ONE, a, MANTISSA_MASK, TernaryOperation.OxF8); + v256 mantissa = mm256_ternarylogic_si256(IMPLICIT_ONE, a, MANTISSA_MASK, TernaryOperation.OxF8); v256 int52 = Avx2.mm256_srlv_epi64(Avx2.mm256_srli_epi64(mantissa, 1), shift_mnt); v256 shifted = Avx2.mm256_sllv_epi64(int52, shift_int); v256 restored = Avx2.mm256_sllv_epi64(Avx2.mm256_and_si256(mantissa, ONE), Avx2.mm256_sub_epi64(shift_int, ONE)); @@ -219,7 +415,7 @@ private static v256 mm256_cvttpd_epi64_BASE(v256 a, bool signed, byte elements = { v256 OVERFLOW = signed ? new v256(1L << 63) : Avx2.mm256_and_si256(sign_mask, new v256(1L << 63)); - v256 inRange = Avx2.mm256_cmpgt_epi64(new v256(BIAS + 63ul), biased_exp); // yes, this excludes many unsigned values but it is following the C(#) standard + v256 inRange = Avx2.mm256_cmpgt_epi64(new v256(BIAS + 63ul), biased_exp); restored = mm256_blendv_si256(OVERFLOW, restored, inRange); } @@ -279,7 +475,7 @@ public static v128 cvtepu16_ps(v128 a) if (Sse2.IsSse2Supported) { v128 EXP_MASK = Sse2.cvtsi64x_si128(0x4B00_4B00_4B00_4B00); - v128 MAGIC = Sse.set1_ps(LIMIT_PRECISE_I16_F32); + v128 MAGIC = Sse.set1_ps(LIMIT_PRECISE_U32_F32); return Sse.sub_ps(Sse2.unpacklo_epi16(a, EXP_MASK), MAGIC); } @@ -336,7 +532,7 @@ public static v128 cvtepu32_pd(v128 a) else { v128 EXP_MASK = Sse2.set1_epi32(0x4330_0000); - v128 MAGIC = Sse2.set1_pd(LIMIT_PRECISE_I32_F64); + v128 MAGIC = Sse2.set1_pd(LIMIT_PRECISE_U64_F64); return Sse2.sub_pd(Sse2.unpacklo_epi32(a, EXP_MASK), MAGIC); } diff --git a/Runtime/XSE Core/Cast/Shuffled Cast.cs b/Runtime/XSE Core/Cast/Shuffled Cast.cs index 40358e7..59542d8 100644 --- a/Runtime/XSE Core/Cast/Shuffled Cast.cs +++ b/Runtime/XSE Core/Cast/Shuffled Cast.cs @@ -139,7 +139,7 @@ public static v128 cvt2x2epu16_ps(v128 a, out v128 hi) if (Sse2.IsSse2Supported) { v128 EXP_MASK = Sse2.set1_epi16(0x4B00); - v128 MAGIC = Sse.set1_ps(LIMIT_PRECISE_I16_F32); + v128 MAGIC = Sse.set1_ps(LIMIT_PRECISE_U32_F32); hi = Sse.sub_ps(Sse2.unpackhi_epi16(a, EXP_MASK), MAGIC); return Sse.sub_ps(Sse2.unpacklo_epi16(a, EXP_MASK), MAGIC); @@ -176,7 +176,7 @@ public static v128 cvt2x2epu32_pd(v128 a, out v128 hi) else { v128 EXP_MASK = Sse2.set1_epi32(0x4330_0000); - v128 MAGIC = Sse2.set1_pd(LIMIT_PRECISE_I32_F64); + v128 MAGIC = Sse2.set1_pd(LIMIT_PRECISE_U64_F64); hi = Sse2.sub_pd(Sse2.unpackhi_epi32(a, EXP_MASK), MAGIC); return Sse2.sub_pd(Sse2.unpacklo_epi32(a, EXP_MASK), MAGIC); @@ -203,6 +203,12 @@ public static v128 cvt2x2epi16_epi8(v128 lo, v128 hi) { if (Sse2.IsSse2Supported) { + if (constexpr.ALL_LE_EPU16(lo, byte.MaxValue) && constexpr.ALL_LE_EPU16(hi, byte.MaxValue)) + { + return Sse2.packus_epi16(lo, hi); + } + + v128 MASK = Sse2.set1_epi16(0x00FF); lo = Sse2.and_si128(lo, MASK); @@ -216,18 +222,33 @@ public static v128 cvt2x2epi16_epi8(v128 lo, v128 hi) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v128 cvt2x2epi32_epi16(v128 lo, v128 hi) { - if (Sse4_1.IsSse41Supported) + if (Sse2.IsSse2Supported) { - v128 MASK = Sse2.set1_epi32(0x0000_FFFF); + if (constexpr.ALL_LE_EPU32(lo, (uint)short.MaxValue) && constexpr.ALL_LE_EPU32(hi, (uint)short.MaxValue)) + { + return Sse2.packs_epi32(lo, hi); + } - lo = Sse2.and_si128(lo, MASK); - hi = Sse2.and_si128(hi, MASK); - return Sse4_1.packus_epi32(lo, hi); - } - else if (Sse2.IsSse2Supported) - { - return Sse2.unpacklo_epi64(cvtepi32_epi16(lo), cvtepi32_epi16(hi)); + if (Sse4_1.IsSse41Supported) + { + if (constexpr.ALL_LE_EPU32(lo, ushort.MaxValue) && constexpr.ALL_LE_EPU32(hi, ushort.MaxValue)) + { + return Sse4_1.packus_epi32(lo, hi); + } + + + v128 MASK = Sse2.set1_epi32(0x0000_FFFF); + + lo = Sse2.and_si128(lo, MASK); + hi = Sse2.and_si128(hi, MASK); + + return Sse4_1.packus_epi32(lo, hi); + } + else + { + return Sse2.unpacklo_epi64(cvtepi32_epi16(lo), cvtepi32_epi16(hi)); + } } else throw new IllegalInstructionException(); } @@ -238,7 +259,7 @@ public static v128 usfcvt2x2ps_epu16(v128 lo, v128 hi) { if (Sse2.IsSse2Supported) { - v128 MAGIC = Sse.set1_ps(LIMIT_PRECISE_I16_F32); + v128 MAGIC = Sse.set1_ps(LIMIT_PRECISE_U32_F32); return cvt2x2epi32_epi16(Sse.add_ps(lo, MAGIC), Sse.add_ps(hi, MAGIC)); } @@ -270,7 +291,7 @@ public static v128 usfcvt2x2pd_epu32(v128 lo, v128 hi) { if (Sse2.IsSse2Supported) { - v128 MAGIC = Sse2.set1_pd(LIMIT_PRECISE_I32_F64); + v128 MAGIC = Sse2.set1_pd(LIMIT_PRECISE_U64_F64); return cvt2x2epi64_epi32(Sse2.add_pd(lo, MAGIC), Sse2.add_pd(hi, MAGIC)); } @@ -282,8 +303,8 @@ public static v128 usfcvtt2x2pd_epu32(v128 lo, v128 hi) { if (Sse2.IsSse2Supported) { - lo = RegisterConversion.ToV128(Unity.Mathematics.math.trunc(RegisterConversion.ToType(lo))); - hi = RegisterConversion.ToV128(Unity.Mathematics.math.trunc(RegisterConversion.ToType(hi))); + lo = RegisterConversion.ToV128(Unity.Mathematics.math.trunc(RegisterConversion.ToDouble2(lo))); + hi = RegisterConversion.ToV128(Unity.Mathematics.math.trunc(RegisterConversion.ToDouble2(hi))); return usfcvt2x2pd_epu32(lo, hi); } @@ -379,7 +400,7 @@ public static v256 mm256_cvt2x2epu16_ps(v256 a, out v256 hi) if (Avx2.IsAvx2Supported) { v256 EXP_MASK = Avx.mm256_set1_epi16(0x4B00); - v256 MAGIC = Avx.mm256_set1_ps(LIMIT_PRECISE_I16_F32); + v256 MAGIC = Avx.mm256_set1_ps(LIMIT_PRECISE_U32_F32); hi = Avx.mm256_sub_ps(Avx2.mm256_unpackhi_epi16(a, EXP_MASK), MAGIC); return Avx.mm256_sub_ps(Avx2.mm256_unpacklo_epi16(a, EXP_MASK), MAGIC); @@ -409,7 +430,7 @@ public static v256 mm256_cvt2x2epu32_pd(v256 a, out v256 hi) if (Avx2.IsAvx2Supported) { v256 EXP_MASK = Avx.mm256_set1_epi32(0x4330_0000); - v256 MAGIC = Avx.mm256_set1_pd(LIMIT_PRECISE_I32_F64); + v256 MAGIC = Avx.mm256_set1_pd(LIMIT_PRECISE_U64_F64); hi = Avx.mm256_sub_pd(Avx2.mm256_unpackhi_epi32(a, EXP_MASK), MAGIC); return Avx.mm256_sub_pd(Avx2.mm256_unpacklo_epi32(a, EXP_MASK), MAGIC); @@ -436,6 +457,12 @@ public static v256 mm256_cvt2x2epi16_epi8(v256 lo, v256 hi) { if (Avx2.IsAvx2Supported) { + if (constexpr.ALL_LE_EPU16(lo, byte.MaxValue) && constexpr.ALL_LE_EPU16(hi, byte.MaxValue)) + { + return Avx2.mm256_packus_epi16(lo, hi); + } + + v256 MASK = Avx.mm256_set1_epi16(0x00FF); lo = Avx2.mm256_and_si256(lo, MASK); @@ -451,6 +478,12 @@ public static v256 mm256_cvt2x2epi32_epi16(v256 lo, v256 hi) { if (Avx2.IsAvx2Supported) { + if (constexpr.ALL_LE_EPU32(lo, ushort.MaxValue) && constexpr.ALL_LE_EPU32(hi, ushort.MaxValue)) + { + return Avx2.mm256_packus_epi32(lo, hi); + } + + v256 MASK = Avx.mm256_set1_epi32(0x0000_FFFF); lo = Avx2.mm256_and_si256(lo, MASK); @@ -477,7 +510,7 @@ public static v256 mm256_usfcvt2x2ps_epu16(v256 lo, v256 hi) { if (Avx2.IsAvx2Supported) { - v256 MAGIC = Avx.mm256_set1_ps(LIMIT_PRECISE_I16_F32); + v256 MAGIC = Avx.mm256_set1_ps(LIMIT_PRECISE_U32_F32); return mm256_cvt2x2epi32_epi16(Avx.mm256_add_ps(lo, MAGIC), Avx.mm256_add_ps(hi, MAGIC)); } @@ -489,7 +522,7 @@ public static v256 mm256_usfcvt2x2pd_epu32(v256 lo, v256 hi) { if (Avx2.IsAvx2Supported) { - v256 MAGIC = Avx.mm256_set1_pd(LIMIT_PRECISE_I32_F64); + v256 MAGIC = Avx.mm256_set1_pd(LIMIT_PRECISE_U64_F64); return mm256_cvt2x2epi64_epi32(Avx.mm256_add_pd(lo, MAGIC), Avx.mm256_add_pd(hi, MAGIC)); } diff --git a/Runtime/XSE Core/Constant/Division/Single/Byte Single Division.cs b/Runtime/XSE Core/Constant/Division/Single/Byte Single Division.cs index 3f07231..cc68809 100644 --- a/Runtime/XSE Core/Constant/Division/Single/Byte Single Division.cs +++ b/Runtime/XSE Core/Constant/Division/Single/Byte Single Division.cs @@ -6,7 +6,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Single/Byte Single Remainder.cs b/Runtime/XSE Core/Constant/Division/Single/Byte Single Remainder.cs index c6d68bf..5141d31 100644 --- a/Runtime/XSE Core/Constant/Division/Single/Byte Single Remainder.cs +++ b/Runtime/XSE Core/Constant/Division/Single/Byte Single Remainder.cs @@ -5,7 +5,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Single/Int Single Division.cs b/Runtime/XSE Core/Constant/Division/Single/Int Single Division.cs index 03d81c2..4c1764e 100644 --- a/Runtime/XSE Core/Constant/Division/Single/Int Single Division.cs +++ b/Runtime/XSE Core/Constant/Division/Single/Int Single Division.cs @@ -3,7 +3,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Single/Int Single Remainder.cs b/Runtime/XSE Core/Constant/Division/Single/Int Single Remainder.cs index 9df0c86..4f33195 100644 --- a/Runtime/XSE Core/Constant/Division/Single/Int Single Remainder.cs +++ b/Runtime/XSE Core/Constant/Division/Single/Int Single Remainder.cs @@ -3,7 +3,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Single/Long Single Division.cs b/Runtime/XSE Core/Constant/Division/Single/Long Single Division.cs index 949ee77..d88974a 100644 --- a/Runtime/XSE Core/Constant/Division/Single/Long Single Division.cs +++ b/Runtime/XSE Core/Constant/Division/Single/Long Single Division.cs @@ -3,7 +3,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Single/Long Single Remainder.cs b/Runtime/XSE Core/Constant/Division/Single/Long Single Remainder.cs index aa4ffb8..c95df43 100644 --- a/Runtime/XSE Core/Constant/Division/Single/Long Single Remainder.cs +++ b/Runtime/XSE Core/Constant/Division/Single/Long Single Remainder.cs @@ -3,7 +3,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Single/SByte Single Division.cs b/Runtime/XSE Core/Constant/Division/Single/SByte Single Division.cs index cf7c4ee..145726b 100644 --- a/Runtime/XSE Core/Constant/Division/Single/SByte Single Division.cs +++ b/Runtime/XSE Core/Constant/Division/Single/SByte Single Division.cs @@ -5,7 +5,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Single/SByte Single Remainder.cs b/Runtime/XSE Core/Constant/Division/Single/SByte Single Remainder.cs index 9758557..3e02307 100644 --- a/Runtime/XSE Core/Constant/Division/Single/SByte Single Remainder.cs +++ b/Runtime/XSE Core/Constant/Division/Single/SByte Single Remainder.cs @@ -3,7 +3,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Single/Short Single Division.cs b/Runtime/XSE Core/Constant/Division/Single/Short Single Division.cs index 5071b88..5540007 100644 --- a/Runtime/XSE Core/Constant/Division/Single/Short Single Division.cs +++ b/Runtime/XSE Core/Constant/Division/Single/Short Single Division.cs @@ -3,7 +3,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Single/Short Single Remainder.cs b/Runtime/XSE Core/Constant/Division/Single/Short Single Remainder.cs index 0aff501..65790e7 100644 --- a/Runtime/XSE Core/Constant/Division/Single/Short Single Remainder.cs +++ b/Runtime/XSE Core/Constant/Division/Single/Short Single Remainder.cs @@ -3,7 +3,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Single/UInt Single Division.cs b/Runtime/XSE Core/Constant/Division/Single/UInt Single Division.cs index 0fff49c..3f23d1b 100644 --- a/Runtime/XSE Core/Constant/Division/Single/UInt Single Division.cs +++ b/Runtime/XSE Core/Constant/Division/Single/UInt Single Division.cs @@ -5,7 +5,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Single/UInt Single Remainder.cs b/Runtime/XSE Core/Constant/Division/Single/UInt Single Remainder.cs index b937da4..664a6f9 100644 --- a/Runtime/XSE Core/Constant/Division/Single/UInt Single Remainder.cs +++ b/Runtime/XSE Core/Constant/Division/Single/UInt Single Remainder.cs @@ -3,7 +3,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Single/ULong Single Division.cs b/Runtime/XSE Core/Constant/Division/Single/ULong Single Division.cs index 9f66442..e8b9b2e 100644 --- a/Runtime/XSE Core/Constant/Division/Single/ULong Single Division.cs +++ b/Runtime/XSE Core/Constant/Division/Single/ULong Single Division.cs @@ -3,7 +3,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Single/ULong Single Remainder.cs b/Runtime/XSE Core/Constant/Division/Single/ULong Single Remainder.cs index da58389..69c96bc 100644 --- a/Runtime/XSE Core/Constant/Division/Single/ULong Single Remainder.cs +++ b/Runtime/XSE Core/Constant/Division/Single/ULong Single Remainder.cs @@ -3,7 +3,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Single/UShort Single Division.cs b/Runtime/XSE Core/Constant/Division/Single/UShort Single Division.cs index a303c7e..3fb8827 100644 --- a/Runtime/XSE Core/Constant/Division/Single/UShort Single Division.cs +++ b/Runtime/XSE Core/Constant/Division/Single/UShort Single Division.cs @@ -3,7 +3,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Single/UShort Single Remainder.cs b/Runtime/XSE Core/Constant/Division/Single/UShort Single Remainder.cs index e1a3672..66fad08 100644 --- a/Runtime/XSE Core/Constant/Division/Single/UShort Single Remainder.cs +++ b/Runtime/XSE Core/Constant/Division/Single/UShort Single Remainder.cs @@ -3,7 +3,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Vector/Byte Vector Division.cs b/Runtime/XSE Core/Constant/Division/Vector/Byte Vector Division.cs index 6bd9224..771acda 100644 --- a/Runtime/XSE Core/Constant/Division/Vector/Byte Vector Division.cs +++ b/Runtime/XSE Core/Constant/Division/Vector/Byte Vector Division.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Vector/Byte Vector Remainder.cs b/Runtime/XSE Core/Constant/Division/Vector/Byte Vector Remainder.cs index 34eac9a..e9382c2 100644 --- a/Runtime/XSE Core/Constant/Division/Vector/Byte Vector Remainder.cs +++ b/Runtime/XSE Core/Constant/Division/Vector/Byte Vector Remainder.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Vector/Int Vector Division.cs b/Runtime/XSE Core/Constant/Division/Vector/Int Vector Division.cs index 4784722..c7e57db 100644 --- a/Runtime/XSE Core/Constant/Division/Vector/Int Vector Division.cs +++ b/Runtime/XSE Core/Constant/Division/Vector/Int Vector Division.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Vector/Int Vector Remainder.cs b/Runtime/XSE Core/Constant/Division/Vector/Int Vector Remainder.cs index ec260ce..3327cd5 100644 --- a/Runtime/XSE Core/Constant/Division/Vector/Int Vector Remainder.cs +++ b/Runtime/XSE Core/Constant/Division/Vector/Int Vector Remainder.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Vector/Long Vector Division.cs b/Runtime/XSE Core/Constant/Division/Vector/Long Vector Division.cs index 9f0fe61..d1af0cc 100644 --- a/Runtime/XSE Core/Constant/Division/Vector/Long Vector Division.cs +++ b/Runtime/XSE Core/Constant/Division/Vector/Long Vector Division.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Vector/Long Vector Remainder.cs b/Runtime/XSE Core/Constant/Division/Vector/Long Vector Remainder.cs index f8e8849..2dc0029 100644 --- a/Runtime/XSE Core/Constant/Division/Vector/Long Vector Remainder.cs +++ b/Runtime/XSE Core/Constant/Division/Vector/Long Vector Remainder.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Vector/SByte Vector Division.cs b/Runtime/XSE Core/Constant/Division/Vector/SByte Vector Division.cs index 6e7c735..9647cb5 100644 --- a/Runtime/XSE Core/Constant/Division/Vector/SByte Vector Division.cs +++ b/Runtime/XSE Core/Constant/Division/Vector/SByte Vector Division.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Vector/SByte Vector Remainder.cs b/Runtime/XSE Core/Constant/Division/Vector/SByte Vector Remainder.cs index c0788a9..23bd7d5 100644 --- a/Runtime/XSE Core/Constant/Division/Vector/SByte Vector Remainder.cs +++ b/Runtime/XSE Core/Constant/Division/Vector/SByte Vector Remainder.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Vector/Short Vector Division.cs b/Runtime/XSE Core/Constant/Division/Vector/Short Vector Division.cs index c6575bf..edd6eba 100644 --- a/Runtime/XSE Core/Constant/Division/Vector/Short Vector Division.cs +++ b/Runtime/XSE Core/Constant/Division/Vector/Short Vector Division.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Vector/Short Vector Remainder.cs b/Runtime/XSE Core/Constant/Division/Vector/Short Vector Remainder.cs index 6db2cca..fb74ce1 100644 --- a/Runtime/XSE Core/Constant/Division/Vector/Short Vector Remainder.cs +++ b/Runtime/XSE Core/Constant/Division/Vector/Short Vector Remainder.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Vector/UInt Vector Division.cs b/Runtime/XSE Core/Constant/Division/Vector/UInt Vector Division.cs index 4e45147..65a58aa 100644 --- a/Runtime/XSE Core/Constant/Division/Vector/UInt Vector Division.cs +++ b/Runtime/XSE Core/Constant/Division/Vector/UInt Vector Division.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Vector/UInt Vector Remainder.cs b/Runtime/XSE Core/Constant/Division/Vector/UInt Vector Remainder.cs index 2f8ee0c..4d1d187 100644 --- a/Runtime/XSE Core/Constant/Division/Vector/UInt Vector Remainder.cs +++ b/Runtime/XSE Core/Constant/Division/Vector/UInt Vector Remainder.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Vector/ULong Vector Division.cs b/Runtime/XSE Core/Constant/Division/Vector/ULong Vector Division.cs index 356a2da..6d9b5b7 100644 --- a/Runtime/XSE Core/Constant/Division/Vector/ULong Vector Division.cs +++ b/Runtime/XSE Core/Constant/Division/Vector/ULong Vector Division.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Vector/ULong Vector Remainder.cs b/Runtime/XSE Core/Constant/Division/Vector/ULong Vector Remainder.cs index 8e6f382..b317d03 100644 --- a/Runtime/XSE Core/Constant/Division/Vector/ULong Vector Remainder.cs +++ b/Runtime/XSE Core/Constant/Division/Vector/ULong Vector Remainder.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Vector/UShort Vector Division.cs b/Runtime/XSE Core/Constant/Division/Vector/UShort Vector Division.cs index cf290c9..4aa0f5f 100644 --- a/Runtime/XSE Core/Constant/Division/Vector/UShort Vector Division.cs +++ b/Runtime/XSE Core/Constant/Division/Vector/UShort Vector Division.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Division/Vector/UShort Vector Remainder.cs b/Runtime/XSE Core/Constant/Division/Vector/UShort Vector Remainder.cs index a777e2c..7c11aca 100644 --- a/Runtime/XSE Core/Constant/Division/Vector/UShort Vector Remainder.cs +++ b/Runtime/XSE Core/Constant/Division/Vector/UShort Vector Remainder.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Macros/Check const Vector value helpers.cs b/Runtime/XSE Core/Constant/Macros/Check const Vector value helpers.cs index 88acd32..89ed580 100644 --- a/Runtime/XSE Core/Constant/Macros/Check const Vector value helpers.cs +++ b/Runtime/XSE Core/Constant/Macros/Check const Vector value helpers.cs @@ -1,9 +1,10 @@ using System.Runtime.CompilerServices; using Unity.Burst.Intrinsics; +using Unity.Mathematics; namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { @@ -5607,6 +5608,236 @@ public static bool ALL_SAME_EPI64(v256 v, byte elements = 4) { return ALL_EQ_EPI64(v, v.SLong0); } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ALL_NAN_PS(v128 v, byte elements = 4) + { + switch (elements) + { + case 2: return IS_TRUE(math.isnan(v.Float0)) + && IS_TRUE(math.isnan(v.Float1)); + + case 3: return IS_TRUE(math.isnan(v.Float0)) + && IS_TRUE(math.isnan(v.Float1)) + && IS_TRUE(math.isnan(v.Float2)); + + default: return IS_TRUE(math.isnan(v.Float0)) + && IS_TRUE(math.isnan(v.Float1)) + && IS_TRUE(math.isnan(v.Float2)) + && IS_TRUE(math.isnan(v.Float3)); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ANY_NAN_PS(v128 v, byte elements = 4) + { + switch (elements) + { + case 2: return IS_TRUE(math.isnan(v.Float0)) + || IS_TRUE(math.isnan(v.Float1)); + + case 3: return IS_TRUE(math.isnan(v.Float0)) + || IS_TRUE(math.isnan(v.Float1)) + || IS_TRUE(math.isnan(v.Float2)); + + default: return IS_TRUE(math.isnan(v.Float0)) + || IS_TRUE(math.isnan(v.Float1)) + || IS_TRUE(math.isnan(v.Float2)) + || IS_TRUE(math.isnan(v.Float3)); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ALL_NOTNAN_PS(v128 v, byte elements = 4) + { + switch (elements) + { + case 2: return IS_TRUE(!math.isnan(v.Float0)) + && IS_TRUE(!math.isnan(v.Float1)); + + case 3: return IS_TRUE(!math.isnan(v.Float0)) + && IS_TRUE(!math.isnan(v.Float1)) + && IS_TRUE(!math.isnan(v.Float2)); + + default: return IS_TRUE(!math.isnan(v.Float0)) + && IS_TRUE(!math.isnan(v.Float1)) + && IS_TRUE(!math.isnan(v.Float2)) + && IS_TRUE(!math.isnan(v.Float3)); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ANY_NOTNAN_PS(v128 v, byte elements = 4) + { + switch (elements) + { + case 2: return IS_TRUE(!math.isnan(v.Float0)) + || IS_TRUE(!math.isnan(v.Float1)); + + case 3: return IS_TRUE(!math.isnan(v.Float0)) + || IS_TRUE(!math.isnan(v.Float1)) + || IS_TRUE(!math.isnan(v.Float2)); + + default: return IS_TRUE(!math.isnan(v.Float0)) + || IS_TRUE(!math.isnan(v.Float1)) + || IS_TRUE(!math.isnan(v.Float2)) + || IS_TRUE(!math.isnan(v.Float3)); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ALL_NAN_PS(v256 v) + { + return IS_TRUE(math.isnan(v.Float0)) + && IS_TRUE(math.isnan(v.Float1)) + && IS_TRUE(math.isnan(v.Float2)) + && IS_TRUE(math.isnan(v.Float3)) + && IS_TRUE(math.isnan(v.Float4)) + && IS_TRUE(math.isnan(v.Float5)) + && IS_TRUE(math.isnan(v.Float6)) + && IS_TRUE(math.isnan(v.Float7)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ANY_NAN_PS(v256 v) + { + return IS_TRUE(math.isnan(v.Float0)) + || IS_TRUE(math.isnan(v.Float1)) + || IS_TRUE(math.isnan(v.Float2)) + || IS_TRUE(math.isnan(v.Float3)) + || IS_TRUE(math.isnan(v.Float4)) + || IS_TRUE(math.isnan(v.Float5)) + || IS_TRUE(math.isnan(v.Float6)) + || IS_TRUE(math.isnan(v.Float7)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ALL_NOTNAN_PS(v256 v) + { + return IS_TRUE(!math.isnan(v.Float0)) + && IS_TRUE(!math.isnan(v.Float1)) + && IS_TRUE(!math.isnan(v.Float2)) + && IS_TRUE(!math.isnan(v.Float3)) + && IS_TRUE(!math.isnan(v.Float4)) + && IS_TRUE(!math.isnan(v.Float5)) + && IS_TRUE(!math.isnan(v.Float6)) + && IS_TRUE(!math.isnan(v.Float7)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ANY_NOTNAN_PS(v256 v) + { + return IS_TRUE(!math.isnan(v.Float0)) + || IS_TRUE(!math.isnan(v.Float1)) + || IS_TRUE(!math.isnan(v.Float2)) + || IS_TRUE(!math.isnan(v.Float3)) + || IS_TRUE(!math.isnan(v.Float4)) + || IS_TRUE(!math.isnan(v.Float5)) + || IS_TRUE(!math.isnan(v.Float6)) + || IS_TRUE(!math.isnan(v.Float7)); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ALL_NAN_PD(v128 v) + { + return IS_TRUE(math.isnan(v.Double0)) + && IS_TRUE(math.isnan(v.Double1)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ANY_NAN_PD(v128 v) + { + return IS_TRUE(math.isnan(v.Double0)) + || IS_TRUE(math.isnan(v.Double1)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ALL_NOTNAN_PD(v128 v) + { + return IS_TRUE(!math.isnan(v.Double0)) + && IS_TRUE(!math.isnan(v.Double1)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ANY_NOTNAN_PD(v128 v) + { + return IS_TRUE(!math.isnan(v.Double0)) + || IS_TRUE(!math.isnan(v.Double1)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ALL_NAN_PD(v256 v, byte elements = 4) + { + if (elements == 3) + { + return IS_TRUE(math.isnan(v.Double0)) + && IS_TRUE(math.isnan(v.Double1)) + && IS_TRUE(math.isnan(v.Double2)); + } + else + { + return IS_TRUE(math.isnan(v.Double0)) + && IS_TRUE(math.isnan(v.Double1)) + && IS_TRUE(math.isnan(v.Double2)) + && IS_TRUE(math.isnan(v.Double3)); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ANY_NAN_PD(v256 v, byte elements = 4) + { + if (elements == 3) + { + return IS_TRUE(math.isnan(v.Double0)) + || IS_TRUE(math.isnan(v.Double1)) + || IS_TRUE(math.isnan(v.Double2)); + } + else + { + return IS_TRUE(math.isnan(v.Double0)) + || IS_TRUE(math.isnan(v.Double1)) + || IS_TRUE(math.isnan(v.Double2)) + || IS_TRUE(math.isnan(v.Double3)); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ALL_NOTNAN_PD(v256 v, byte elements = 4) + { + if (elements == 3) + { + return IS_TRUE(!math.isnan(v.Double0)) + && IS_TRUE(!math.isnan(v.Double1)) + && IS_TRUE(!math.isnan(v.Double2)); + } + else + { + return IS_TRUE(!math.isnan(v.Double0)) + && IS_TRUE(!math.isnan(v.Double1)) + && IS_TRUE(!math.isnan(v.Double2)) + && IS_TRUE(!math.isnan(v.Double3)); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ANY_NOTNAN_PD(v256 v, byte elements = 4) + { + if (elements == 3) + { + return IS_TRUE(!math.isnan(v.Double0)) + || IS_TRUE(!math.isnan(v.Double1)) + || IS_TRUE(!math.isnan(v.Double2)); + } + else + { + return IS_TRUE(!math.isnan(v.Double0)) + || IS_TRUE(!math.isnan(v.Double1)) + || IS_TRUE(!math.isnan(v.Double2)) + || IS_TRUE(!math.isnan(v.Double3)); + } + } } } } diff --git a/Runtime/XSE Core/Constant/Macros/Scalar.cs b/Runtime/XSE Core/Constant/Macros/Scalar.cs index d1c596d..91e4d07 100644 --- a/Runtime/XSE Core/Constant/Macros/Scalar.cs +++ b/Runtime/XSE Core/Constant/Macros/Scalar.cs @@ -3,7 +3,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Macros/Vector Assume Intrinsic Helper.cs b/Runtime/XSE Core/Constant/Macros/Vector Assume Intrinsic Helper.cs index 6490bc2..c5256b7 100644 --- a/Runtime/XSE Core/Constant/Macros/Vector Assume Intrinsic Helper.cs +++ b/Runtime/XSE Core/Constant/Macros/Vector Assume Intrinsic Helper.cs @@ -1,10 +1,11 @@ using System.Runtime.CompilerServices; using Unity.Burst.CompilerServices; using Unity.Burst.Intrinsics; +using Unity.Mathematics; namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { @@ -1830,6 +1831,83 @@ public static void ASSUME_LE_PD(v256 v, double cmpVal) Hint.Assume(v.Double2 <= cmpVal); Hint.Assume(v.Double3 <= cmpVal); } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ASSUME_NAN_PS(v128 v) + { + Hint.Assume(math.isnan(v.Float0)); + Hint.Assume(math.isnan(v.Float1)); + Hint.Assume(math.isnan(v.Float2)); + Hint.Assume(math.isnan(v.Float3)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ASSUME_NAN_PD(v128 v) + { + Hint.Assume(math.isnan(v.Double0)); + Hint.Assume(math.isnan(v.Double1)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ASSUME_NAN_PS(v256 v) + { + Hint.Assume(math.isnan(v.Float0)); + Hint.Assume(math.isnan(v.Float1)); + Hint.Assume(math.isnan(v.Float2)); + Hint.Assume(math.isnan(v.Float3)); + Hint.Assume(math.isnan(v.Float4)); + Hint.Assume(math.isnan(v.Float5)); + Hint.Assume(math.isnan(v.Float6)); + Hint.Assume(math.isnan(v.Float7)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ASSUME_NAN_PD(v256 v) + { + Hint.Assume(math.isnan(v.Double0)); + Hint.Assume(math.isnan(v.Double1)); + Hint.Assume(math.isnan(v.Double2)); + Hint.Assume(math.isnan(v.Double3)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ASSUME_NOTNAN_PS(v128 v) + { + Hint.Assume(!math.isnan(v.Float0)); + Hint.Assume(!math.isnan(v.Float1)); + Hint.Assume(!math.isnan(v.Float2)); + Hint.Assume(!math.isnan(v.Float3)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ASSUME_NOTNAN_PD(v128 v) + { + Hint.Assume(!math.isnan(v.Double0)); + Hint.Assume(!math.isnan(v.Double1)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ASSUME_NOTNAN_PS(v256 v) + { + Hint.Assume(!math.isnan(v.Float0)); + Hint.Assume(!math.isnan(v.Float1)); + Hint.Assume(!math.isnan(v.Float2)); + Hint.Assume(!math.isnan(v.Float3)); + Hint.Assume(!math.isnan(v.Float4)); + Hint.Assume(!math.isnan(v.Float5)); + Hint.Assume(!math.isnan(v.Float6)); + Hint.Assume(!math.isnan(v.Float7)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ASSUME_NOTNAN_PD(v256 v) + { + Hint.Assume(!math.isnan(v.Double0)); + Hint.Assume(!math.isnan(v.Double1)); + Hint.Assume(!math.isnan(v.Double2)); + Hint.Assume(!math.isnan(v.Double3)); + } } } } diff --git a/Runtime/XSE Core/Constant/Multiplication/Byte Single Multiplication.cs b/Runtime/XSE Core/Constant/Multiplication/Byte Single Multiplication.cs index 02a3f96..096e2ca 100644 --- a/Runtime/XSE Core/Constant/Multiplication/Byte Single Multiplication.cs +++ b/Runtime/XSE Core/Constant/Multiplication/Byte Single Multiplication.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Constant/Multiplication/SByte Single Multiplication.cs b/Runtime/XSE Core/Constant/Multiplication/SByte Single Multiplication.cs index 61470b2..98f464c 100644 --- a/Runtime/XSE Core/Constant/Multiplication/SByte Single Multiplication.cs +++ b/Runtime/XSE Core/Constant/Multiplication/SByte Single Multiplication.cs @@ -4,7 +4,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { public static partial class constexpr { diff --git a/Runtime/XSE Core/Exceptions/ConstantException.cs b/Runtime/XSE Core/Exceptions/ConstantException.cs deleted file mode 100644 index cced189..0000000 --- a/Runtime/XSE Core/Exceptions/ConstantException.cs +++ /dev/null @@ -1,37 +0,0 @@ -// In Burst compiled code, the exception Message is not displayed, which makes it not user friendly (June 11th '22) - -//using System; -//using System.Runtime.CompilerServices; -//using Unity.Burst.CompilerServices; -// -//namespace MaxMath -//{ -// public class ConstantException : Exception -// { -// private ConstantException() -// { } -// -// public ConstantException(string paramName, string funcName) -// : base($"The \"{ funcName }\" parameter \"{ paramName }\" was expected to be constant.") -// { -// -// } -// -// // In Burst compiled code, the exception Message is not displayed, which makes it not user friendly (June 11th '22) -// public static void ThrowIfNonConstant(T value, string paramName, [CallerMemberName] string funcName = null) -// where T : unmanaged -// { -// if (Constant.IsConstantExpression(1)) -// { -// if (Constant.IsConstantExpression(value)) -// { -// return; -// } -// else -// { -// throw new ConstantException(paramName, funcName); -// } -// } -// } -// } -//} \ No newline at end of file diff --git a/Runtime/XSE Core/Fast Approximate/Accurate Reciprocal Square Root.cs b/Runtime/XSE Core/Fast Approximate/Accurate Reciprocal Square Root.cs index 1aa8d06..213bc8c 100644 --- a/Runtime/XSE Core/Fast Approximate/Accurate Reciprocal Square Root.cs +++ b/Runtime/XSE Core/Fast Approximate/Accurate Reciprocal Square Root.cs @@ -5,7 +5,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v128 rsqrt23_ps(v128 a) diff --git a/Runtime/XSE Core/Fast Approximate/Accurate Reciprocal.cs b/Runtime/XSE Core/Fast Approximate/Accurate Reciprocal.cs index 3e597e1..780d0fb 100644 --- a/Runtime/XSE Core/Fast Approximate/Accurate Reciprocal.cs +++ b/Runtime/XSE Core/Fast Approximate/Accurate Reciprocal.cs @@ -5,7 +5,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static v128 rcp23_ps(v128 a) diff --git a/Runtime/XSE Core/Fast Approximate/DBL Approximate Inverse Square Root.cs b/Runtime/XSE Core/Fast Approximate/DBL Approximate Inverse Square Root.cs index dcaec3e..6bf443b 100644 --- a/Runtime/XSE Core/Fast Approximate/DBL Approximate Inverse Square Root.cs +++ b/Runtime/XSE Core/Fast Approximate/DBL Approximate Inverse Square Root.cs @@ -5,7 +5,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { internal const ulong MAGIC_RSQRT_PD_GUESS = 0x5FE6_EB50_C7B5_37A9ul; internal const double MAGIC_RSQRT_PD_MUL = 0.7039522544782403d; diff --git a/Runtime/XSE Core/Fast Approximate/DBL Approximate Reciprocal.cs b/Runtime/XSE Core/Fast Approximate/DBL Approximate Reciprocal.cs index acaae2e..7ea2606 100644 --- a/Runtime/XSE Core/Fast Approximate/DBL Approximate Reciprocal.cs +++ b/Runtime/XSE Core/Fast Approximate/DBL Approximate Reciprocal.cs @@ -5,7 +5,7 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { internal const long MAGIC_RCP_PD = 0x7FDE_6238_22FC_16E6; diff --git a/Runtime/XSE Core/Insert Extract.cs b/Runtime/XSE Core/Insert Extract.cs new file mode 100644 index 0000000..4bfa0b9 --- /dev/null +++ b/Runtime/XSE Core/Insert Extract.cs @@ -0,0 +1,842 @@ +using System; +using System.Runtime.CompilerServices; +using Unity.Burst.Intrinsics; +using Unity.Burst.CompilerServices; +using Unity.Mathematics; +using DevTools; + +using static Unity.Burst.Intrinsics.X86; + +namespace MaxMath.Intrinsics +{ + unsafe public static partial class Xse + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte extract_epi8(v128 a, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Sse4_1.IsSse41Supported) + { + switch (i) + { + case 15: return Sse4_1.extract_epi8(a, 15); + case 14: return Sse4_1.extract_epi8(a, 14); + case 13: return Sse4_1.extract_epi8(a, 13); + case 12: return Sse4_1.extract_epi8(a, 12); + case 11: return Sse4_1.extract_epi8(a, 11); + case 10: return Sse4_1.extract_epi8(a, 10); + case 9: return Sse4_1.extract_epi8(a, 9); + case 8: return Sse4_1.extract_epi8(a, 8); + case 7: return Sse4_1.extract_epi8(a, 7); + case 6: return Sse4_1.extract_epi8(a, 6); + case 5: return Sse4_1.extract_epi8(a, 5); + case 4: return Sse4_1.extract_epi8(a, 4); + case 3: return Sse4_1.extract_epi8(a, 3); + case 2: return Sse4_1.extract_epi8(a, 2); + case 1: return Sse4_1.extract_epi8(a, 1); + case 0: return (byte)Sse2.cvtsi128_si32(a); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else if (Sse2.IsSse2Supported) + { + switch (i) + { + case 15: return (byte)((uint)Sse2.extract_epi16(a, 7) >> 8); + case 14: return (byte)Sse2.extract_epi16(a, 7); + case 13: return (byte)((uint)Sse2.extract_epi16(a, 6) >> 8); + case 12: return (byte)Sse2.extract_epi16(a, 6); + case 11: return (byte)((uint)Sse2.extract_epi16(a, 5) >> 8); + case 10: return (byte)Sse2.extract_epi16(a, 5); + case 9: return (byte)((uint)Sse2.extract_epi16(a, 4) >> 8); + case 8: return (byte)Sse2.extract_epi16(a, 4); + case 7: return (byte)((ulong)Sse2.cvtsi128_si64x(a) >> 56); + case 6: return (byte)((ulong)Sse2.cvtsi128_si64x(a) >> 48); + case 5: return (byte)((ulong)Sse2.cvtsi128_si64x(a) >> 40); + case 4: return (byte)((ulong)Sse2.cvtsi128_si64x(a) >> 32); + case 3: return (byte)((uint)Sse2.cvtsi128_si32(a) >> 24); + case 2: return (byte)((uint)Sse2.cvtsi128_si32(a) >> 16); + case 1: return (byte)((uint)Sse2.cvtsi128_si32(a) >> 8); + case 0: return (byte)Sse2.cvtsi128_si32(a); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 15); + + return *((byte*)&a + i); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort extract_epi16(v128 a, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Sse2.IsSse2Supported) + { + switch (i) + { + case 7: return Sse2.extract_epi16(a, 7); + case 6: return Sse2.extract_epi16(a, 6); + case 5: return Sse2.extract_epi16(a, 5); + case 4: return Sse2.extract_epi16(a, 4); + case 3: return Sse2.extract_epi16(a, 3); + case 2: return Sse2.extract_epi16(a, 2); + case 1: return Sse2.extract_epi16(a, 1); + case 0: return (ushort)Sse2.cvtsi128_si32(a); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 7); + + return *((ushort*)&a + i); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint extract_epi32(v128 a, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Sse4_1.IsSse41Supported) + { + switch (i) + { + case 3: return (uint)Sse4_1.extract_epi32(a, 3); + case 2: return (uint)Sse4_1.extract_epi32(a, 2); + case 1: return (uint)Sse4_1.extract_epi32(a, 1); + case 0: return (uint)Sse2.cvtsi128_si32(a); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else if (Sse2.IsSse2Supported) + { + switch (i) + { + case 3: return (uint)Sse2.cvtsi128_si32(Sse2.bsrli_si128(a, 3 * sizeof(int))); + case 2: return (uint)Sse2.cvtsi128_si32(Sse2.bsrli_si128(a, 2 * sizeof(int))); + case 1: return (uint)((ulong)Sse2.cvtsi128_si64x(a) >> 32); + case 0: return (uint)Sse2.cvtsi128_si32(a); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 3); + + return *((uint*)&a + i); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong extract_epi64(v128 a, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Sse4_1.IsSse41Supported) + { + switch (i) + { + case 1: return (ulong)Sse4_1.extract_epi64(a, 1); + case 0: return (ulong)Sse2.cvtsi128_si64x(a); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else if (Sse2.IsSse2Supported) + { + switch (i) + { + case 1: return (ulong)Sse2.cvtsi128_si64x(Sse2.bsrli_si128(a, 1 * sizeof(ulong))); + case 0: return (ulong)Sse2.cvtsi128_si64x(a); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 1); + + return *((ulong*)&a + i); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float extract_ps(v128 a, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Sse4_1.IsSse41Supported) + { + switch (i) + { + case 3: return Sse4_1.extractf_ps(a, 3); + case 2: return Sse4_1.extractf_ps(a, 2); + case 1: return Sse4_1.extractf_ps(a, 1); + case 0: return math.asfloat(Sse2.cvtsi128_si32(a)); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else if (Sse2.IsSse2Supported) + { + switch (i) + { + case 3: return math.asfloat(Sse2.cvtsi128_si32(Sse2.bsrli_si128(a, 3 * sizeof(float)))); + case 2: return math.asfloat(Sse2.cvtsi128_si32(Sse2.bsrli_si128(a, 2 * sizeof(float)))); + case 1: return math.asfloat(Sse2.cvtsi128_si32(Sse2.bsrli_si128(a, 1 * sizeof(float)))); + case 0: return math.asfloat(Sse2.cvtsi128_si32(a)); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 3); + + return *((float*)&a + i); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double extract_pd(v128 a, byte i) + { + return math.asdouble(extract_epi64(a, i)); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte mm256_extract_epi8(v256 a, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Avx2.IsAvx2Supported) + { + switch (i) + { + case 31: return (byte)Avx2.mm256_extract_epi8(a, 31); + case 30: return (byte)Avx2.mm256_extract_epi8(a, 30); + case 29: return (byte)Avx2.mm256_extract_epi8(a, 29); + case 28: return (byte)Avx2.mm256_extract_epi8(a, 28); + case 27: return (byte)Avx2.mm256_extract_epi8(a, 27); + case 26: return (byte)Avx2.mm256_extract_epi8(a, 26); + case 25: return (byte)Avx2.mm256_extract_epi8(a, 25); + case 24: return (byte)Avx2.mm256_extract_epi8(a, 24); + case 23: return (byte)Avx2.mm256_extract_epi8(a, 23); + case 22: return (byte)Avx2.mm256_extract_epi8(a, 22); + case 21: return (byte)Avx2.mm256_extract_epi8(a, 21); + case 20: return (byte)Avx2.mm256_extract_epi8(a, 20); + case 19: return (byte)Avx2.mm256_extract_epi8(a, 19); + case 18: return (byte)Avx2.mm256_extract_epi8(a, 18); + case 17: return (byte)Avx2.mm256_extract_epi8(a, 17); + case 16: return (byte)Avx2.mm256_extract_epi8(a, 16); + case 15: return (byte)Avx2.mm256_extract_epi8(a, 15); + case 14: return (byte)Avx2.mm256_extract_epi8(a, 14); + case 13: return (byte)Avx2.mm256_extract_epi8(a, 13); + case 12: return (byte)Avx2.mm256_extract_epi8(a, 12); + case 11: return (byte)Avx2.mm256_extract_epi8(a, 11); + case 10: return (byte)Avx2.mm256_extract_epi8(a, 10); + case 9: return (byte)Avx2.mm256_extract_epi8(a, 9); + case 8: return (byte)Avx2.mm256_extract_epi8(a, 8); + case 7: return (byte)Avx2.mm256_extract_epi8(a, 7); + case 6: return (byte)Avx2.mm256_extract_epi8(a, 6); + case 5: return (byte)Avx2.mm256_extract_epi8(a, 5); + case 4: return (byte)Avx2.mm256_extract_epi8(a, 4); + case 3: return (byte)Avx2.mm256_extract_epi8(a, 3); + case 2: return (byte)Avx2.mm256_extract_epi8(a, 2); + case 1: return (byte)Avx2.mm256_extract_epi8(a, 1); + case 0: return (byte)Sse2.cvtsi128_si32(Avx.mm256_castsi256_si128(a)); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 31); + + return *((byte*)&a + i); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort mm256_extract_epi16(v256 a, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Avx2.IsAvx2Supported) + { + switch (i) + { + case 15: return (ushort)Avx2.mm256_extract_epi16(a, 15); + case 14: return (ushort)Avx2.mm256_extract_epi16(a, 14); + case 13: return (ushort)Avx2.mm256_extract_epi16(a, 13); + case 12: return (ushort)Avx2.mm256_extract_epi16(a, 12); + case 11: return (ushort)Avx2.mm256_extract_epi16(a, 11); + case 10: return (ushort)Avx2.mm256_extract_epi16(a, 10); + case 9: return (ushort)Avx2.mm256_extract_epi16(a, 9); + case 8: return (ushort)Avx2.mm256_extract_epi16(a, 8); + case 7: return (ushort)Avx2.mm256_extract_epi16(a, 7); + case 6: return (ushort)Avx2.mm256_extract_epi16(a, 6); + case 5: return (ushort)Avx2.mm256_extract_epi16(a, 5); + case 4: return (ushort)Avx2.mm256_extract_epi16(a, 4); + case 3: return (ushort)Avx2.mm256_extract_epi16(a, 3); + case 2: return (ushort)Avx2.mm256_extract_epi16(a, 2); + case 1: return (ushort)Avx2.mm256_extract_epi16(a, 1); + case 0: return (ushort)Sse2.cvtsi128_si32(Avx.mm256_castsi256_si128(a)); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 15); + + return *((ushort*)&a + i); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint mm256_extract_epi32(v256 a, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Avx.IsAvxSupported) + { + switch (i) + { + case 7: return (uint)Avx.mm256_extract_epi32(a, 7); + case 6: return (uint)Avx.mm256_extract_epi32(a, 6); + case 5: return (uint)Avx.mm256_extract_epi32(a, 5); + case 4: return (uint)Avx.mm256_extract_epi32(a, 4); + case 3: return (uint)Avx.mm256_extract_epi32(a, 3); + case 2: return (uint)Avx.mm256_extract_epi32(a, 2); + case 1: return (uint)Avx.mm256_extract_epi32(a, 1); + case 0: return (uint)Sse2.cvtsi128_si32(Avx.mm256_castsi256_si128(a)); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 7); + + return *((uint*)&a + i); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong mm256_extract_epi64(v256 a, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Avx.IsAvxSupported) + { + switch (i) + { + case 3: return (ulong)Avx.mm256_extract_epi64(a, 3); + case 2: return (ulong)Avx.mm256_extract_epi64(a, 2); + case 1: return (ulong)Avx.mm256_extract_epi64(a, 1); + case 0: return (ulong)Sse2.cvtsi128_si64x(Avx.mm256_castsi256_si128(a)); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 3); + + return *((ulong*)&a + i); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float mm256_extract_ps(v256 a, byte i) + { + return math.asfloat(mm256_extract_epi32(a, i)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double mm256_extract_pd(v256 a, byte i) + { + return math.asdouble(mm256_extract_epi64(a, i)); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 insert_epi8(v128 a, byte v, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Sse4_1.IsSse41Supported) + { + switch (i) + { + case 15: return Sse4_1.insert_epi8(a, v, 15); + case 14: return Sse4_1.insert_epi8(a, v, 14); + case 13: return Sse4_1.insert_epi8(a, v, 13); + case 12: return Sse4_1.insert_epi8(a, v, 12); + case 11: return Sse4_1.insert_epi8(a, v, 11); + case 10: return Sse4_1.insert_epi8(a, v, 10); + case 9: return Sse4_1.insert_epi8(a, v, 9); + case 8: return Sse4_1.insert_epi8(a, v, 8); + case 7: return Sse4_1.insert_epi8(a, v, 7); + case 6: return Sse4_1.insert_epi8(a, v, 6); + case 5: return Sse4_1.insert_epi8(a, v, 5); + case 4: return Sse4_1.insert_epi8(a, v, 4); + case 3: return Sse4_1.insert_epi8(a, v, 3); + case 2: return Sse4_1.insert_epi8(a, v, 2); + case 1: return Sse4_1.insert_epi8(a, v, 1); + case 0: return Sse4_1.insert_epi8(a, v, 0); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else if (Sse2.IsSse2Supported) + { + switch (i) + { + case 15: + { + ushort s = Sse2.extract_epi16(a, 7); + *((byte*)&s + 1) = v; + + return Sse2.insert_epi16(a, s, 7); + } + case 14: + { + ushort s = Sse2.extract_epi16(a, 7); + *(byte*)&s = v; + + return Sse2.insert_epi16(a, s, 7); + } + case 13: + { + ushort s = Sse2.extract_epi16(a, 6); + *((byte*)&s + 1) = v; + + return Sse2.insert_epi16(a, s, 6); + } + case 12: + { + ushort s = Sse2.extract_epi16(a, 6); + *(byte*)&s = v; + + return Sse2.insert_epi16(a, s, 6); + } + case 11: + { + ushort s = Sse2.extract_epi16(a, 5); + *((byte*)&s + 1) = v; + + return Sse2.insert_epi16(a, s, 5); + } + case 10: + { + ushort s = Sse2.extract_epi16(a, 5); + *(byte*)&s = v; + + return Sse2.insert_epi16(a, s, 5); + } + case 9: + { + ushort s = Sse2.extract_epi16(a, 4); + *((byte*)&s + 1) = v; + + return Sse2.insert_epi16(a, s, 4); + } + case 8: + { + ushort s = Sse2.extract_epi16(a, 4); + *(byte*)&s = v; + + return Sse2.insert_epi16(a, s, 4); + } + case 7: + { + v128 MASK = Sse2.cvtsi64x_si128(unchecked((long)0xFF00_0000_0000_0000)); + + return Sse2.or_si128(Sse2.cvtsi64x_si128((long)v << 56), Sse2.andnot_si128(MASK, a)); + } + case 6: + { + v128 MASK = Sse2.cvtsi64x_si128(0xFF_0000_0000_0000); + + return Sse2.or_si128(Sse2.cvtsi64x_si128((long)v << 48), Sse2.andnot_si128(MASK, a)); + } + case 5: + { + v128 MASK = Sse2.cvtsi64x_si128(0xFF00_0000_0000); + + return Sse2.or_si128(Sse2.cvtsi64x_si128((long)v << 40), Sse2.andnot_si128(MASK, a)); + } + case 4: + { + v128 MASK = Sse2.cvtsi64x_si128(0xFF_0000_0000); + + return Sse2.or_si128(Sse2.cvtsi64x_si128((long)v << 32), Sse2.andnot_si128(MASK, a)); + } + case 3: + { + v128 MASK = Sse2.cvtsi32_si128(unchecked((int)0xFF00_0000)); + + return Sse2.or_si128(Sse2.cvtsi32_si128(v << 24), Sse2.andnot_si128(MASK, a)); + } + case 2: + { + v128 MASK = Sse2.cvtsi32_si128(0xFF_0000); + + return Sse2.or_si128(Sse2.cvtsi32_si128(v << 16), Sse2.andnot_si128(MASK, a)); + } + case 1: + { + v128 MASK = Sse2.cvtsi32_si128(0xFF00); + + return Sse2.or_si128(Sse2.cvtsi32_si128(v << 8), Sse2.andnot_si128(MASK, a)); + } + case 0: + { + v128 MASK = Sse2.cvtsi32_si128(0xFF); + + return Sse2.or_si128(Sse2.cvtsi32_si128(v), Sse2.andnot_si128(MASK, a)); + } + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 15); + + *((byte*)&a + i) = v; + + return a; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 insert_epi16(v128 a, ushort v, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Sse2.IsSse2Supported) + { + switch (i) + { + case 7: return Sse2.insert_epi16(a, v, 7); + case 6: return Sse2.insert_epi16(a, v, 6); + case 5: return Sse2.insert_epi16(a, v, 5); + case 4: return Sse2.insert_epi16(a, v, 4); + case 3: return Sse2.insert_epi16(a, v, 3); + case 2: return Sse2.insert_epi16(a, v, 2); + case 1: return Sse2.insert_epi16(a, v, 1); + case 0: return Sse2.insert_epi16(a, v, 0); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 7); + + *((ushort*)&a + i) = v; + + return a; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 insert_epi32(v128 a, uint v, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Sse4_1.IsSse41Supported) + { + switch (i) + { + case 3: return Sse4_1.insert_epi32(a, (int)v, 3); + case 2: return Sse4_1.insert_epi32(a, (int)v, 2); + case 1: return Sse4_1.insert_epi32(a, (int)v, 1); + case 0: return Sse4_1.insert_epi32(a, (int)v, 0); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + if (Sse2.IsSse2Supported) + { + switch (i) + { + case 3: return Sse2.or_si128(Sse2.bslli_si128(Sse2.cvtsi32_si128((int)v), 3 * sizeof(int)), Sse2.and_si128(new v128(-1, -1, -1, 0), a)); + case 2: return Sse2.or_si128(Sse2.bslli_si128(Sse2.cvtsi32_si128((int)v), 2 * sizeof(int)), Sse2.and_si128(new v128(-1, -1, 0, -1), a)); + case 1: return Sse2.or_si128(Sse2.cvtsi64x_si128((long)v << 32), Sse2.andnot_si128(Sse2.cvtsi64x_si128(unchecked((long)0xFFFF_FFFF_0000_0000)), a)); + case 0: return Sse2.or_si128(Sse2.cvtsi32_si128((int)v), Sse2.andnot_si128(Sse2.cvtsi32_si128(unchecked((int)0xFFFF_FFFF)), a)); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 3); + + *((uint*)&a + i) = v; + + return a; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 insert_epi64(v128 a, ulong v, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Sse4_1.IsSse41Supported) + { + switch (i) + { + case 1: return Sse4_1.insert_epi64(a, (long)v, 1); + case 0: return Sse4_1.insert_epi64(a, (long)v, 0); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + if (Sse2.IsSse2Supported) + { + switch (i) + { + case 1: return Sse2.unpacklo_epi64(a, Sse2.cvtsi64x_si128((long)v)); + case 0: return Sse2.or_si128(Sse2.cvtsi64x_si128((long)v), Sse2.andnot_si128(Sse2.cvtsi64x_si128(-1L), a)); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 1); + + *((ulong*)&a + i) = v; + + return a; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 insert_ps(v128 a, float v, byte i) + { + return insert_epi32(a, math.asuint(v), i); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 insert_pd(v128 a, double v, byte i) + { + return insert_epi64(a, math.asulong(v), i); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_insert_epi8(v256 a, byte v, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Avx.IsAvxSupported) + { + switch (i) + { + case 31: return Avx.mm256_insert_epi8(a, (sbyte)v, 31); + case 30: return Avx.mm256_insert_epi8(a, (sbyte)v, 30); + case 29: return Avx.mm256_insert_epi8(a, (sbyte)v, 29); + case 28: return Avx.mm256_insert_epi8(a, (sbyte)v, 28); + case 27: return Avx.mm256_insert_epi8(a, (sbyte)v, 27); + case 26: return Avx.mm256_insert_epi8(a, (sbyte)v, 26); + case 25: return Avx.mm256_insert_epi8(a, (sbyte)v, 25); + case 24: return Avx.mm256_insert_epi8(a, (sbyte)v, 24); + case 23: return Avx.mm256_insert_epi8(a, (sbyte)v, 23); + case 22: return Avx.mm256_insert_epi8(a, (sbyte)v, 22); + case 21: return Avx.mm256_insert_epi8(a, (sbyte)v, 21); + case 20: return Avx.mm256_insert_epi8(a, (sbyte)v, 20); + case 19: return Avx.mm256_insert_epi8(a, (sbyte)v, 19); + case 18: return Avx.mm256_insert_epi8(a, (sbyte)v, 18); + case 17: return Avx.mm256_insert_epi8(a, (sbyte)v, 17); + case 16: return Avx.mm256_insert_epi8(a, (sbyte)v, 16); + case 15: return Avx.mm256_insert_epi8(a, (sbyte)v, 15); + case 14: return Avx.mm256_insert_epi8(a, (sbyte)v, 14); + case 13: return Avx.mm256_insert_epi8(a, (sbyte)v, 13); + case 12: return Avx.mm256_insert_epi8(a, (sbyte)v, 12); + case 11: return Avx.mm256_insert_epi8(a, (sbyte)v, 11); + case 10: return Avx.mm256_insert_epi8(a, (sbyte)v, 10); + case 9: return Avx.mm256_insert_epi8(a, (sbyte)v, 9); + case 8: return Avx.mm256_insert_epi8(a, (sbyte)v, 8); + case 7: return Avx.mm256_insert_epi8(a, (sbyte)v, 7); + case 6: return Avx.mm256_insert_epi8(a, (sbyte)v, 6); + case 5: return Avx.mm256_insert_epi8(a, (sbyte)v, 5); + case 4: return Avx.mm256_insert_epi8(a, (sbyte)v, 4); + case 3: return Avx.mm256_insert_epi8(a, (sbyte)v, 3); + case 2: return Avx.mm256_insert_epi8(a, (sbyte)v, 2); + case 1: return Avx.mm256_insert_epi8(a, (sbyte)v, 1); + case 0: return Avx.mm256_insert_epi8(a, (sbyte)v, 0); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 31); + + *((byte*)&a + i) = v; + + return a; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_insert_epi16(v256 a, ushort v, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Avx.IsAvxSupported) + { + switch (i) + { + case 15: return Avx.mm256_insert_epi16(a, (short)v, 15); + case 14: return Avx.mm256_insert_epi16(a, (short)v, 14); + case 13: return Avx.mm256_insert_epi16(a, (short)v, 13); + case 12: return Avx.mm256_insert_epi16(a, (short)v, 12); + case 11: return Avx.mm256_insert_epi16(a, (short)v, 11); + case 10: return Avx.mm256_insert_epi16(a, (short)v, 10); + case 9: return Avx.mm256_insert_epi16(a, (short)v, 9); + case 8: return Avx.mm256_insert_epi16(a, (short)v, 8); + case 7: return Avx.mm256_insert_epi16(a, (short)v, 7); + case 6: return Avx.mm256_insert_epi16(a, (short)v, 6); + case 5: return Avx.mm256_insert_epi16(a, (short)v, 5); + case 4: return Avx.mm256_insert_epi16(a, (short)v, 4); + case 3: return Avx.mm256_insert_epi16(a, (short)v, 3); + case 2: return Avx.mm256_insert_epi16(a, (short)v, 2); + case 1: return Avx.mm256_insert_epi16(a, (short)v, 1); + case 0: return Avx.mm256_insert_epi16(a, (short)v, 0); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 15); + + *((ushort*)&a + i) = v; + + return a; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_insert_epi32(v256 a, uint v, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Avx.IsAvxSupported) + { + switch (i) + { + case 7: return Avx.mm256_insert_epi32(a, (int)v, 7); + case 6: return Avx.mm256_insert_epi32(a, (int)v, 6); + case 5: return Avx.mm256_insert_epi32(a, (int)v, 5); + case 4: return Avx.mm256_insert_epi32(a, (int)v, 4); + case 3: return Avx.mm256_insert_epi32(a, (int)v, 3); + case 2: return Avx.mm256_insert_epi32(a, (int)v, 2); + case 1: return Avx.mm256_insert_epi32(a, (int)v, 1); + case 0: return Avx.mm256_insert_epi32(a, (int)v, 0); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 7); + + *((uint*)&a + i) = v; + + return a; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_insert_epi64(v256 a, ulong v, byte i) + { + if (Constant.IsConstantExpression(i)) + { + if (Avx.IsAvxSupported) + { + switch (i) + { + case 3: return Avx.mm256_insert_epi64(a, (long)v, 3); + case 2: return Avx.mm256_insert_epi64(a, (long)v, 2); + case 1: return Avx.mm256_insert_epi64(a, (long)v, 1); + case 0: return Avx.mm256_insert_epi64(a, (long)v, 0); + + default: throw new IndexOutOfRangeException(i.ToString()); + } + } + else throw new IllegalInstructionException(); + } + else + { +Assert.IsNotGreater(i, 3); + + *((ulong*)&a + i) = v; + + return a; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_insert_ps(v256 a, float v, byte i) + { + return mm256_insert_epi32(a, math.asuint(v), i); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v256 mm256_insert_pd(v256 a, double v, byte i) + { + return mm256_insert_epi64(a, math.asulong(v), i); + } + } +} diff --git a/Runtime/XSE Core/Insert Extract.cs.meta b/Runtime/XSE Core/Insert Extract.cs.meta new file mode 100644 index 0000000..3582a02 --- /dev/null +++ b/Runtime/XSE Core/Insert Extract.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3bb06e3a385632746bc3ab823748b436 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/XSE Core/Ternary Logic/OpCode Generator.cs b/Runtime/XSE Core/Ternary Logic/OpCode Generator.cs new file mode 100644 index 0000000..a5b02ac --- /dev/null +++ b/Runtime/XSE Core/Ternary Logic/OpCode Generator.cs @@ -0,0 +1,33 @@ +using System; + +namespace MaxMath.Intrinsics +{ + unsafe public static partial class Xse + { + /// + /// Generates an opcode for and given any possible three valued boolean expression, + /// where the parameter order of '' maps to the parameter order of the mentioned intrinsics, + /// i.e. " = (a, b, c) => a ^ (b ? c : !a)" is equivalent to "(a ^ c) | !b" and maps to ternarylogic_si128(a, b, c, 0x7B). + /// + /// + /// is a managed type and cannot be used in Burst compiled code, even if the value could be calulated at compile time. + /// This is a tool intended for logging the opcode to the console. + /// + public static byte __ternlog_opcode__(Func ternaryBooleanExpression) + { + int result = 0; + + for (int i = 0; i < 8; i++) + { + int a = (i & 0b100) >> 2; + int b = (i & 0b010) >> 1; + int c = (i & 0b001) >> 0; + + bool truthValue = ternaryBooleanExpression(*(bool*)&a, *(bool*)&b, *(bool*)&c); + result |= *(byte*)&truthValue << i; + } + + return (byte)result; + } + } +} diff --git a/Runtime/XSE Core/Ternary Logic/OpCode Generator.cs.meta b/Runtime/XSE Core/Ternary Logic/OpCode Generator.cs.meta new file mode 100644 index 0000000..2f30004 --- /dev/null +++ b/Runtime/XSE Core/Ternary Logic/OpCode Generator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 181f982a5212acd468a44976f37fbcf0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/XSE Core/Ternary Logic/Codes.cs b/Runtime/XSE Core/Ternary Logic/OpCodes.cs similarity index 91% rename from Runtime/XSE Core/Ternary Logic/Codes.cs rename to Runtime/XSE Core/Ternary Logic/OpCodes.cs index efe5d37..e17c97a 100644 --- a/Runtime/XSE Core/Ternary Logic/Codes.cs +++ b/Runtime/XSE Core/Ternary Logic/OpCodes.cs @@ -77,16 +77,16 @@ public enum TernaryOperation : byte /// (A ^ B) & (A ^ C) Ox18, - /// ~((A & B)) & (B ^ ~C) + /// ~(A & B) & (B ^ ~C) Ox19, - /// ~((A & B)) & (A ^ C) + /// ~(A & B) & (A ^ C) Ox1A, /// C ? ~A : ~B Ox1B, - /// ~((A & C)) & (A ^ B) + /// ~(A & C) & (A ^ B) Ox1C, /// B ? ~A : ~C @@ -113,10 +113,10 @@ public enum TernaryOperation : byte /// (A ^ B) & (B ^ C) Ox24, - /// ~((A & B)) & (A ^ ~C) + /// ~(A & B) & (A ^ ~C) Ox25, - /// ~((A & B)) & (B ^ C) + /// ~(A & B) & (B ^ C) Ox26, /// C ? ~B : ~A @@ -158,7 +158,7 @@ public enum TernaryOperation : byte /// ~B Ox33, - /// ~((B & C)) & (A ^ B) + /// ~(B & C) & (A ^ B) Ox34, /// A ? ~B : ~C @@ -203,7 +203,7 @@ public enum TernaryOperation : byte /// (A ^ C) & (B ^ C) Ox42, - /// ~((A & C)) & (A ^ ~B) + /// ~(A & C) & (A ^ ~B) Ox43, /// B & ~C @@ -212,7 +212,7 @@ public enum TernaryOperation : byte /// ~C & (~A | B) Ox45, - /// ~((A & C)) & (B ^ C) + /// ~(A & C) & (B ^ C) Ox46, /// B ? ~C : ~A @@ -248,7 +248,7 @@ public enum TernaryOperation : byte /// ~C & (A | ~B) Ox51, - /// ~((B & C)) & (A ^ C) + /// ~(B & C) & (A ^ C) Ox52, /// A ? ~C : ~B @@ -389,19 +389,19 @@ public enum TernaryOperation : byte /// A & (B & C) Ox8O, - /// ~((A ^ C)) & (A ^ ~B) + /// ~(A ^ C) & (A ^ ~B) Ox81, /// C & ~(B ^ A) Ox82, - /// ~((A ^ B)) & (~A | C) + /// ~(A ^ B) & (~A | C) Ox83, /// B & ~(A ^ C) Ox84, - /// ~((A ^ C)) & (B | ~C) + /// ~(A ^ C) & (B | ~C) Ox85, /// (B | C) & (C ^ (A ^ B)) @@ -413,16 +413,16 @@ public enum TernaryOperation : byte /// C & B Ox88, - /// ~((B ^ C)) & (~A | B) + /// ~(B ^ C) & (~A | B) Ox89, - /// ~((~B & A)) & C + /// ~(~B & A) & C Ox8A, /// B ? C : ~A Ox8B, - /// ~((~C & A)) & B + /// ~(~C & A) & B Ox8C, /// C ? B : ~A @@ -437,7 +437,7 @@ public enum TernaryOperation : byte /// A & ~(B ^ C) Ox9O, - /// ~((B ^ C)) & (A | ~B) + /// ~(B ^ C) & (A | ~B) Ox91, /// (A | C) & (C ^ (A ^ B)) @@ -458,7 +458,7 @@ public enum TernaryOperation : byte /// A ? ~(B ^ C) : ~(B & C) Ox97, - /// ~((B ^ C)) & (A | B) + /// ~(B ^ C) & (A | B) Ox98, /// ~(C ^ B) @@ -485,16 +485,16 @@ public enum TernaryOperation : byte /// C & A OxAO, - /// ~((A ^ C)) & (A | ~B) + /// ~(A ^ C) & (A | ~B) OxA1, - /// ~((~A & B)) & C + /// ~(~A & B) & C OxA2, /// A ? C : ~B OxA3, - /// ~((A ^ C)) & (A | B) + /// ~(A ^ C) & (A | B) OxA4, /// ~(C ^ A) @@ -530,7 +530,7 @@ public enum TernaryOperation : byte /// C | ~A OxAF, - /// ~((~C & B)) & A + /// ~(~C & B) & A OxBO, /// C ? A : ~B @@ -581,16 +581,16 @@ public enum TernaryOperation : byte /// B & A OxCO, - /// ~((A ^ B)) & (A | ~C) + /// ~(A ^ B) & (A | ~C) OxC1, - /// ~((A ^ B)) & (A | C) + /// ~(A ^ B) & (A | C) OxC2, /// ~(B ^ A) OxC3, - /// ~((~A & C)) & B + /// ~(~A & C) & B OxC4, /// A ? B : ~C diff --git a/Runtime/XSE Core/Ternary Logic/Codes.cs.meta b/Runtime/XSE Core/Ternary Logic/OpCodes.cs.meta similarity index 100% rename from Runtime/XSE Core/Ternary Logic/Codes.cs.meta rename to Runtime/XSE Core/Ternary Logic/OpCodes.cs.meta diff --git a/Runtime/XSE Core/Vector Masks/Interpret Result Bitmask.cs b/Runtime/XSE Core/Vector Masks/Interpret Result Bitmask.cs index 5292ac0..db11928 100644 --- a/Runtime/XSE Core/Vector Masks/Interpret Result Bitmask.cs +++ b/Runtime/XSE Core/Vector Masks/Interpret Result Bitmask.cs @@ -5,10 +5,10 @@ namespace MaxMath.Intrinsics { - unsafe public static partial class Xse + unsafe public static partial class Xse { [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int truemsk(int elements) + internal static int truemsk(int elements) where T : unmanaged { return (int)((1L << (sizeof(T) * elements)) - 1); @@ -345,7 +345,7 @@ public static bool notallfalse_epi128(v128 a, int elements) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool mm256_notallfalse_epi128(v256 a, int elements) + public static bool mm256_notallfalse_epi256(v256 a, int elements) where T : unmanaged { if (Avx2.IsAvx2Supported) diff --git a/Runtime/XSE Core/Vector Masks/MoveMask Reverse.cs b/Runtime/XSE Core/Vector Masks/Inverse MoveMask.cs similarity index 100% rename from Runtime/XSE Core/Vector Masks/MoveMask Reverse.cs rename to Runtime/XSE Core/Vector Masks/Inverse MoveMask.cs diff --git a/Runtime/XSE Core/Vector Masks/MoveMask Reverse.cs.meta b/Runtime/XSE Core/Vector Masks/Inverse MoveMask.cs.meta similarity index 100% rename from Runtime/XSE Core/Vector Masks/MoveMask Reverse.cs.meta rename to Runtime/XSE Core/Vector Masks/Inverse MoveMask.cs.meta diff --git a/Runtime/XSE Core/Vector Masks/Set all Ones.cs b/Runtime/XSE Core/Vector Masks/Set all Ones.cs index f519fbe..a284b71 100644 --- a/Runtime/XSE Core/Vector Masks/Set all Ones.cs +++ b/Runtime/XSE Core/Vector Masks/Set all Ones.cs @@ -1,8 +1,6 @@ using System.Runtime.CompilerServices; using Unity.Burst.Intrinsics; -using static Unity.Burst.Intrinsics.X86; - namespace MaxMath.Intrinsics { unsafe public static partial class Xse diff --git a/Runtime/__Internal/HalfExtensions.cs b/Runtime/__Internal/HalfExtensions.cs index 362d59e..1fcbf3e 100644 --- a/Runtime/__Internal/HalfExtensions.cs +++ b/Runtime/__Internal/HalfExtensions.cs @@ -1,5 +1,8 @@ using System.Runtime.CompilerServices; using Unity.Mathematics; +using MaxMath.Intrinsics; + +using static MaxMath.maxmath; namespace MaxMath { @@ -16,5 +19,121 @@ internal static bool IsNotZero(this half h) { return (h.value & 0x7FFFu) != 0u; } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool IsEqualTo(this half lhs, half rhs) + { + if (Xse.constexpr.IS_TRUE(IsZero(lhs))) + { + return IsZero(rhs); + } + else if (Xse.constexpr.IS_TRUE(IsZero(rhs))) + { + return IsZero(lhs); + } + + bool nan = !isnan(lhs) & !isnan(rhs); + bool zero = IsZero(lhs) & IsZero(rhs); + bool value = lhs.value == rhs.value; + + return nan & (zero | value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool IsNotEqualTo(this half lhs, half rhs) + { + if (Xse.constexpr.IS_TRUE(IsZero(lhs))) + { + return IsNotZero(rhs); + } + else if (Xse.constexpr.IS_TRUE(IsZero(rhs))) + { + return IsNotZero(lhs); + } + + bool bothZero = IsZero(new half{ value = (ushort)(lhs.value | rhs.value) }); + bool value = lhs.value != rhs.value; + bool nan = isnan(lhs) | isnan(rhs); + + return nan | !bothZero | value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool IsLessThan(this half lhs, half rhs) + { + if (Xse.constexpr.IS_TRUE(rhs.value == 0) || Xse.constexpr.IS_TRUE(rhs.value == 0x8000)) + { + bool negative = lhs.value > 0x7FFF; + bool notZero = (lhs.value & 0x7FFF) != 0; + + return !isnan(lhs) & (notZero & negative); + } + if (Xse.constexpr.IS_TRUE(lhs.value == 0) || Xse.constexpr.IS_TRUE(lhs.value == 0x8000)) + { + bool positive = rhs.value < 0x8000; + bool notZero = (rhs.value & 0x7FFF) != 0; + + return !isnan(rhs) & (positive & notZero); + } + + + int signA = lhs.value >> 15; + int signB = rhs.value >> 15; + + bool notNaN = !isnan(lhs) & !isnan(rhs); + bool equalSigns = signA == signB; + bool differentValues = lhs.value != rhs.value; + bool notBothZero = (ushort)((lhs.value | rhs.value) << 1) != 0; + + bool ifEqualSigns = differentValues & (tobool(signA) ^ (rhs.value > lhs.value)); + bool ifOppositeSigns = notBothZero & tobool(signA); + + return notNaN & (equalSigns ? ifEqualSigns : ifOppositeSigns); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool IsLessThanOrEqualTo(this half lhs, half rhs) + { + if (Xse.constexpr.IS_TRUE(rhs.value == 0) || Xse.constexpr.IS_TRUE(rhs.value == 0x8000)) + { + bool intLEzero = 1 > (short)lhs.value; + + return !isnan(lhs) & intLEzero; + } + if (Xse.constexpr.IS_TRUE(lhs.value == 0) || Xse.constexpr.IS_TRUE(lhs.value == 0x8000)) + { + bool uintGEzero = (short)rhs.value > 0; + bool negativeZero = rhs.value == 0x8000; + + return !isnan(rhs) & (uintGEzero | negativeZero); + } + + + int signA = lhs.value >> 15; + int signB = rhs.value >> 15; + + bool notNaN = !isnan(lhs) & !isnan(rhs); + bool equalSigns = signA == signB; + bool equalValues = lhs.value == rhs.value; + bool bothZero = (ushort)((lhs.value | rhs.value) << 1) == 0; + + bool ifEqualSigns = equalValues | (tobool(signA) ^ (rhs.value > lhs.value)); + bool ifOppositeSigns = bothZero | tobool(signA); + + return notNaN & (equalSigns ? ifEqualSigns : ifOppositeSigns); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool IsGreaterThan(this half lhs, half rhs) + { + return rhs.IsLessThan(lhs); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool IsGreaterThanOrEqualTo(this half lhs, half rhs) + { + return rhs.IsLessThanOrEqualTo(lhs); + } } } \ No newline at end of file diff --git a/Runtime/__Internal/Int128/Constant/Divide.cs b/Runtime/__Internal/Int128/Constant/Divide.cs index a582d3f..8c54c4d 100644 --- a/Runtime/__Internal/Int128/Constant/Divide.cs +++ b/Runtime/__Internal/Int128/Constant/Divide.cs @@ -94,210 +94,18 @@ internal static UInt128 divuint128(UInt128 left, UInt128 right) { return hi >> m.shift; } - ////10 - //UInt128 mul = new UInt128(0x6666_6666_6666_6667, 0x6666_6666_6666_6666), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 2; - // - ////100 - //UInt128 mul = new UInt128(0x8F5C_28F5_C28F_5C29, 0x28F5_C28F_5C28_F5C2), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 4; - // - ////1000 - //UInt128 mul = new UInt128(0xB22D_0E56_0418_9375, 0x4189_374B_C6A7_EF9D), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 8; - // - ////10000 - //UInt128 mul = new UInt128(0xF4F0_D844_D013_A92B, 0x346D_C5D6_3886_594A), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 11; - // - ////100000 - //UInt128 mul = new UInt128(0xC3F3_E037_0CDC_8755, 0x29F1_6B11_C6D1_E108), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 14; - // - ////1000000 - //UInt128 mul = new UInt128(0x5A63_F9A4_9C2C_1B11, 0x0863_7BD0_5AF6_C69B), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 15; - // - ////10000000 - //UInt128 mul = new UInt128(0x1E99_483B_0234_8DA7, 0x6B5F_CA6A_F2BD_215E), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 22; - // - ////100000000 - //UInt128 mul = new UInt128(0x7EE1_0695_9B5D_3E1F, 0x55E6_3B88_C230_E77E), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 25; - // - ////1000000000 - //UInt128 mul = new UInt128(0x98B4_0544_7C4A_9819, 0x44B8_2FA0_9B5A_52CB), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 28; - // - ////10000000000 - //UInt128 mul = new UInt128(0xAD5C_D103_96A2_1347, 0x36F9_BFB3_AF7B_756F), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 31; - // - ////100000000000 - //UInt128 mul = new UInt128(0x7BC7_B4D2_8A9C_EBA5, 0x57F5_FF85_E592_557F), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 35; - // - ////1000000000000 - //UInt128 mul = new UInt128(0xFE4F_E1ED_D10B_9175, 0x232F_3302_5BD4_2232), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 37; - // - ////10000000000000 - //UInt128 mul = new UInt128(0xCA19_697C_81AC_1BEF, 0x384B_84D0_92ED_0384), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 41; - // - ////100000000000000 - //UInt128 mul = new UInt128(0xA9C2_4260_CF79_C64B, 0x5A12_6E1A_84AE_6C07), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 45; - // - ////1000000000000000 - //UInt128 mul = new UInt128(0x87CE_9B80_A5FB_0509, 0x480E_BE7B_9D58_566C), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 48; - // - ////10000000000000000 - //UInt128 mul = new UInt128(0xD30B_AF9A_1E62_6A6D, 0x39A5_652F_B113_7856), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 51; - // - ////100000000000000000 - //UInt128 mul = new UInt128(0x426F_BFAE_7EB5_21F1, 0x2E1D_EA8C_8DA9_2D12), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 54; - // - ////1000000000000000000 - //UInt128 mul = new UInt128(0x73AF_F322_E624_39FD, 0x0939_2EE8_E921_D5D0), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 55; - // - ////10000000000000000000 - //UInt128 mul = new UInt128(0x9598_F4F1_E836_1973, 0x760F_253E_DB4A_B0D2), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 62; - // - ////100000000000000000000 - //UInt128 mul = new UInt128(0x2F39_4219_2484_46BB, 0x0000_0000_0000_0000), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 0; - // - ////1000000000000000000000 - //UInt128 mul = new UInt128(0x1DA0_5074_DA7B_EED4, 0x0000_0000_0000_0097), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 13; - // - ////10000000000000000000000 - //UInt128 mul = new UInt128(0x5324_C68B_12DD_6339, 0xF1C9_0080_BAF7_2CB1), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 73; - // - ////100000000000000000000000 - //UInt128 mul = new UInt128(0xDD6D_C14F_03C5_E0A5, 0x305B_6680_2564_A289), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 74; - // - ////1000000000000000000000000 - //UInt128 mul = new UInt128(0xC492_6A96_7279_3543, 0x9ABE_14CD_4475_3B52), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 79; - // - ////10000000000000000000000000 - //UInt128 mul = new UInt128(0x3A83_DDBD_83F5_2205, 0xF796_87AE_D3EE_C551), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 83; - // - ////100000000000000000000000000 - //UInt128 mul = new UInt128(0x4A9B_257F_0195_40CF, 0x6309_0312_BB2C_4EED), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 85; - // - ////1000000000000000000000000000 - //UInt128 mul = new UInt128(0x3BAF_5132_67AA_9A3F, 0x4F3A_68DB_C8F0_3F24), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 88; - // - ////10000000000000000000000000000 - //UInt128 mul = new UInt128(0x8BCA_9D6E_1888_53FD, 0xFD87_B5F2_8300_CA0D), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 93; - // - ////100000000000000000000000000000 - //UInt128 mul = new UInt128(0x096E_E458_13A0_4331, 0xCAD2_F7F5_359A_3B3E), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 96; - // - ////1000000000000000000000000000000 - //UInt128 mul = new UInt128(0x424B_06F3_529A_051B, 0x4484_BFEE_BC29_F863), - //umul256(left, mul, out UInt128 hi, lo:false); - //UInt128 t = left - hi; - //t >>= 1; - //hi += t; - //hi >>= 99; - // - //return hi; - // - ////10000000000000000000000000000000 - //UInt128 mul = new UInt128(0x01D5_9F29_0EE1_9DAF, 0x039D_6658_9687_F9E9), - //umul256(left, mul, out UInt128 hi, lo:false); - //UInt128 t = left - hi; - //t >>= 1; - //hi += t; - //hi >>= 102; - // - //return hi; - // - ////100000000000000000000000000000000 - //UInt128 mul = new UInt128(0xCFBC_31DB_4B02_95E5, 0x9F62_3D5A_8A73_2974), - //umul256(left, mul, out UInt128 hi, lo:false); - //UInt128 t = left - hi; - //t >>= 1; - //hi += t; - //hi >>= 106; - // - //return hi; - // - ////1000000000000000000000000000000000 - //UInt128 mul = new UInt128(0xECB1_AD8A_EACD_D58F, 0xA627_4BBD_D0FA_DD61), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 109; - // - ////10000000000000000000000000000000000 - //UInt128 mul = new UInt128(0xBD5A_F13B_EF0B_113F, 0x84EC_3C97_DA62_4AB4), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 112; - // - ////100000000000000000000000000000000000 - //UInt128 mul = new UInt128(0x955E_4EC6_4B44_E865, 0xD4AD_2DBF_C3D0_7787), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 116; - // - ////1000000000000000000000000000000000000 - //UInt128 mul = new UInt128(0x6EF2_85E8_EAE8_5CF5, 0x5512_124C_B4B9_C969), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 118; - // - ////10000000000000000000000000000000000000 - //UInt128 mul = new UInt128(0x7E50_D641_77DA_2E55, 0x881C_EA14_545C_7575), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 122; - // - ////100000000000000000000000000000000000000 - //UInt128 mul = new UInt128(0xCB73_DE9A_C648_2511, 0x6CE3_EE76_A9E3_912A), - //umul256(left, mul, out UInt128 hi, lo:false); - //return hi >> 125; + } + + internal static UInt128 divrem10(UInt128 x, out ulong rem) + { + UInt128 mul = new UInt128(0xCCCC_CCCC_CCCC_CCCD, 0xCCCC_CCCC_CCCC_CCCC); + Common.umul256(x, mul, out UInt128 hi, lo: false); + UInt128 q = hi >> 3; + + UInt128 q10 = __const.shluint128(q, 3) + __const.shluint128(q, 1); + + rem = (x - q10).lo64; + return q; } } } diff --git a/Runtime/__Internal/Lookup Tables/Factorial.cs b/Runtime/__Internal/Lookup Tables/Factorial.cs new file mode 100644 index 0000000..b2198e2 --- /dev/null +++ b/Runtime/__Internal/Lookup Tables/Factorial.cs @@ -0,0 +1,23 @@ +namespace MaxMath +{ + internal static partial class LUT + { + internal static class FACTORIAL + { + internal const byte MAX_INVERSE_FACTORIAL_U8 = 5; + internal const byte MAX_INVERSE_FACTORIAL_S8 = 5; + + internal const byte MAX_INVERSE_FACTORIAL_U16 = 8; + internal const byte MAX_INVERSE_FACTORIAL_S16 = 7; + + internal const byte MAX_INVERSE_FACTORIAL_U32 = 12; + internal const byte MAX_INVERSE_FACTORIAL_S32 = 12; + + internal const byte MAX_INVERSE_FACTORIAL_U64 = 20; + internal const byte MAX_INVERSE_FACTORIAL_S64 = 20; + + internal const byte MAX_INVERSE_FACTORIAL_U128 = 34; + internal const byte MAX_INVERSE_FACTORIAL_S128 = 33; + } + } +} diff --git a/Runtime/__Internal/Lookup Tables/Factorial.cs.meta b/Runtime/__Internal/Lookup Tables/Factorial.cs.meta new file mode 100644 index 0000000..4f87644 --- /dev/null +++ b/Runtime/__Internal/Lookup Tables/Factorial.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 05ce2d6b0749afe4b983ff0d42404422 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/__Internal/Lookup Tables/Floating Point - Integer Conversion.cs b/Runtime/__Internal/Lookup Tables/Floating Point - Integer Conversion.cs index 3065d6b..8907abc 100644 --- a/Runtime/__Internal/Lookup Tables/Floating Point - Integer Conversion.cs +++ b/Runtime/__Internal/Lookup Tables/Floating Point - Integer Conversion.cs @@ -7,8 +7,8 @@ internal static class CVT_INT_FP public const ulong USF_CVT_EPU64_PD_LIMIT = (1ul << 52) - 1; public const long ABS_MASK_USF_CVT_EPI64_PD_LIMIT = 1L << 51; - internal const float LIMIT_PRECISE_I16_F32 = 8_388_608f; - internal const double LIMIT_PRECISE_I32_F64 = 4_503_599_627_370_496d; + internal const float LIMIT_PRECISE_U32_F32 = 8_388_608f; + internal const double LIMIT_PRECISE_U64_F64 = 4_503_599_627_370_496d; } } } diff --git a/Runtime/__Internal/Register-Type Conversions/AVX size with SSE instructions.cs b/Runtime/__Internal/Register-Type Conversions/AVX size with SSE instructions.cs index 0c2db3f..2b75b17 100644 --- a/Runtime/__Internal/Register-Type Conversions/AVX size with SSE instructions.cs +++ b/Runtime/__Internal/Register-Type Conversions/AVX size with SSE instructions.cs @@ -1,7 +1,6 @@ using System.Runtime.CompilerServices; using Unity.Burst.Intrinsics; using MaxMath.Intrinsics; -using Unity.Mathematics; using static Unity.Burst.Intrinsics.X86; using static MaxMath.LUT.CVT_INT_FP; @@ -72,7 +71,7 @@ internal static int8 Short8ToInt8(short8 x) v128 lo = Sse4_1.cvtepi16_epi32(x); v128 hi = Sse4_1.cvtepi16_epi32(Sse2.bsrli_si128(x, 4 * sizeof(short))); - return new int8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + return new int8(RegisterConversion.ToInt4(lo), RegisterConversion.ToInt4(hi)); } else if (Sse2.IsSse2Supported) { @@ -80,7 +79,7 @@ internal static int8 Short8ToInt8(short8 x) v128 lo = Sse2.unpacklo_epi16(x, negativeMask); v128 hi = Sse2.unpackhi_epi16(x, negativeMask); - return new int8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + return new int8(RegisterConversion.ToInt4(lo), RegisterConversion.ToInt4(hi)); } else throw new IllegalInstructionException(); } @@ -97,7 +96,7 @@ internal static int8 UShort8ToInt8(ushort8 x) v128 lo = Sse4_1.cvtepu16_epi32(x); v128 hi = Sse4_1.cvtepu16_epi32(Sse2.bsrli_si128(x, 4 * sizeof(ushort))); - return new int8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + return new int8(RegisterConversion.ToInt4(lo), RegisterConversion.ToInt4(hi)); } else if (Sse2.IsSse2Supported) { @@ -105,7 +104,7 @@ internal static int8 UShort8ToInt8(ushort8 x) v128 lo = Sse2.unpacklo_epi16(x, ZERO); v128 hi = Sse2.unpackhi_epi16(x, ZERO); - return new int8(RegisterConversion.ToType(lo), RegisterConversion.ToType(hi)); + return new int8(RegisterConversion.ToInt4(lo), RegisterConversion.ToInt4(hi)); } else throw new IllegalInstructionException(); } @@ -220,7 +219,7 @@ internal static v128 UShort8To_Float8_SSE2(v128 a, out v128 hi) if (Sse2.IsSse2Supported) { v128 EXP_MASK = Sse2.set1_epi16(0x4B00); - v128 MAGIC = Sse.set1_ps(LIMIT_PRECISE_I16_F32); + v128 MAGIC = Sse.set1_ps(LIMIT_PRECISE_U32_F32); hi = Sse.sub_ps(Sse2.unpackhi_epi16(a, EXP_MASK), MAGIC); return Sse.sub_ps(Sse2.unpacklo_epi16(a, EXP_MASK), MAGIC); diff --git a/Runtime/__Internal/Register-Type Conversions/Convert Boolean Register.cs b/Runtime/__Internal/Register-Type Conversions/Convert Boolean Register.cs index 889b957..81c737c 100644 --- a/Runtime/__Internal/Register-Type Conversions/Convert Boolean Register.cs +++ b/Runtime/__Internal/Register-Type Conversions/Convert Boolean Register.cs @@ -9,23 +9,21 @@ namespace MaxMath unsafe internal static partial class RegisterConversion { [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static T IsTrue8(v128 input) - where T : unmanaged + internal static v128 IsTrue8(v128 input) { if (Sse2.IsSse2Supported) { - return ToType(Xse.negmask_epi8(input)); + return Xse.neg_epi8(input); } else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static T IsFalse8(v128 input) - where T : unmanaged + internal static v128 IsFalse8(v128 input) { if (Sse2.IsSse2Supported) { - return ToType(Xse.inc_epi8(input)); + return Xse.inc_epi8(input); } else throw new IllegalInstructionException(); } @@ -35,7 +33,7 @@ internal static v256 IsTrue8(v256 input) { if (Avx2.IsAvx2Supported) { - return Avx2.mm256_abs_epi8(input); + return Xse.mm256_neg_epi8(input); } else throw new IllegalInstructionException(); } @@ -52,23 +50,21 @@ internal static v256 IsFalse8(v256 input) [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static T IsTrue16(v128 input) - where T : unmanaged + internal static v128 IsTrue16(v128 input) { if (Sse2.IsSse2Supported) { - return ToType(IsTrue8(Sse2.packs_epi16(input, input))); + return IsTrue8(Sse2.packs_epi16(input, input)); } else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static T IsFalse16(v128 input) - where T : unmanaged + internal static v128 IsFalse16(v128 input) { if (Sse2.IsSse2Supported) { - return ToType(IsFalse8(Sse2.packs_epi16(input, input))); + return IsFalse8(Sse2.packs_epi16(input, input)); } else throw new IllegalInstructionException(); } @@ -81,7 +77,7 @@ internal static v128 IsTrue16(v256 input) v128 lo = Avx.mm256_castsi256_si128(input); v128 hi = Avx2.mm256_extracti128_si256(input, 1); - return IsTrue8(Sse2.packs_epi16(lo, hi)); + return IsTrue8(Sse2.packs_epi16(lo, hi)); } else throw new IllegalInstructionException(); } @@ -94,19 +90,28 @@ internal static v128 IsFalse16(v256 input) v128 lo = Avx.mm256_castsi256_si128(input); v128 hi = Avx2.mm256_extracti128_si256(input, 1); - return IsFalse8(Sse2.packs_epi16(lo, hi)); + return IsFalse8(Sse2.packs_epi16(lo, hi)); } else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static T IsTrue32(v128 input) - where T : unmanaged + internal static v128 IsTrue32(v128 input) { if (Sse2.IsSse2Supported) { - return ToType(IsTrue16(Sse2.packs_epi32(input, input))); + return IsTrue16(Sse2.packs_epi32(input, input)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 IsFalse32(v128 input) + { + if (Sse2.IsSse2Supported) + { + return IsFalse16(Sse2.packs_epi32(input, input)); } else throw new IllegalInstructionException(); } @@ -121,7 +126,7 @@ internal static v128 IsTrue32(v256 input) v128 _16 = Sse2.packs_epi32(lo, hi); - return IsTrue8(Sse2.packs_epi16(_16, _16)); + return IsTrue8(Sse2.packs_epi16(_16, _16)); } else if (Avx.IsAvxSupported) { @@ -130,7 +135,7 @@ internal static v128 IsTrue32(v256 input) v128 _16 = Sse2.packs_epi32(lo, hi); - return IsTrue8(Sse2.packs_epi16(_16, _16)); + return IsTrue8(Sse2.packs_epi16(_16, _16)); } else throw new IllegalInstructionException(); } @@ -145,7 +150,7 @@ internal static v128 IsFalse32(v256 input) v128 _16 = Sse2.packs_epi32(lo, hi); - return IsFalse8(Sse2.packs_epi16(_16, _16)); + return IsFalse8(Sse2.packs_epi16(_16, _16)); } else if (Avx.IsAvxSupported) { @@ -154,60 +159,48 @@ internal static v128 IsFalse32(v256 input) v128 _16 = Sse2.packs_epi32(lo, hi); - return IsTrue8(Sse2.packs_epi16(_16, _16)); + return IsTrue8(Sse2.packs_epi16(_16, _16)); } else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static T IsTrue64(v128 input) - where T : unmanaged + internal static int IsTrue64(v128 input) { if (Sse2.IsSse2Supported) { - int r = 0x0101 & Sse2.movemask_epi8(input); - - return *(T*)&r; + return 0x0101 & Sse2.movemask_epi8(input); } else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static T IsFalse64(v128 input) - where T : unmanaged + internal static int IsFalse64(v128 input) { if (Sse2.IsSse2Supported) { - int r = maxmath.andnot(0x0101, Sse2.movemask_epi8(input)); - - return *(T*)&r; + return maxmath.andnot(0x0101, Sse2.movemask_epi8(input)); } else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static T IsTrue64(v256 input) - where T : unmanaged + internal static int IsTrue64(v256 input) { if (Avx2.IsAvx2Supported) { - int r = 0x0101_0101 & Avx2.mm256_movemask_epi8(input); - - return *(T*)&r; + return 0x0101_0101 & Avx2.mm256_movemask_epi8(input); } else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static T IsFalse64(v256 input) - where T : unmanaged + internal static int IsFalse64(v256 input) { if (Avx2.IsAvx2Supported) { - int r = maxmath.andnot(0x0101_0101, Avx2.mm256_movemask_epi8(input)); - - return *(T*)&r; + return maxmath.andnot(0x0101_0101, Avx2.mm256_movemask_epi8(input)); } else throw new IllegalInstructionException(); } diff --git a/Runtime/__Internal/Register-Type Conversions/Convert Numeric Register.cs b/Runtime/__Internal/Register-Type Conversions/Convert Numeric Register.cs index 3dd224b..a2a7664 100644 --- a/Runtime/__Internal/Register-Type Conversions/Convert Numeric Register.cs +++ b/Runtime/__Internal/Register-Type Conversions/Convert Numeric Register.cs @@ -1,7 +1,7 @@ using System.Runtime.CompilerServices; -using Unity.Burst.Intrinsics; using Unity.Burst.CompilerServices; -using MaxMath.Intrinsics; +using Unity.Burst.Intrinsics; +using Unity.Mathematics; using static Unity.Burst.Intrinsics.X86; @@ -11,143 +11,857 @@ unsafe internal static partial class RegisterConversion { [SkipLocalsInit] [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v256 ToV256(T input) - where T : unmanaged + internal static v256 ToV256(double3 input) { - if (sizeof(T) == sizeof(v256)) + if (Avx.IsAvxSupported) { - return *(v256*)&input; + v256 result = Avx.mm256_undefined_pd(); + + result.Double0 = input.x; + result.Double1 = input.y; + result.Double2 = input.z; + + return result; } - else + else throw new IllegalInstructionException(); + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v256 ToV256(double4 input) + { + if (Avx.IsAvxSupported) { - v256 r; - if (Avx.IsAvxSupported) + return new v256 { - r = Avx.mm256_undefined_si256(); - } - *(v128*)&r = *(v128*)&input; - *((long*)&r + 2) = *((long*)&input + 2); - - return r; + Double0 = input.x, + Double1 = input.y, + Double2 = input.z, + Double3 = input.w + }; } + else throw new IllegalInstructionException(); + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(double2 input) + { + return new v128 + { + Double0 = input.x, + Double1 = input.y + }; } [SkipLocalsInit] [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ToV128(T input) - where T : unmanaged + internal static v128 ToV128(double input) { - v128 r; if (Avx.IsAvxSupported) { - r = Avx.undefined_si128(); + v128 result = Avx.undefined_pd(); + + result.Double0 = input; + + return result; } + else + { + v128 result; + v128* dummyPtr = &result; + + result.Double0 = input; - if (sizeof(T) == sizeof(v128)) + return result; + } + } + + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(float input) + { + if (Avx.IsAvxSupported) { - return *(v128*)&input; + v128 result = Avx.undefined_ps(); + + result.Float0 = input; + + return result; } - else if (sizeof(T) == 12) + else { - *(long*)&r = *(long*)&input; - *((int*)&r + 2) = *((int*)&input + 2); + v128 result; + v128* dummyPtr = &result; + + result.Float0 = input; + + return result; } - else if (sizeof(T) == 8) + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(float2 input) + { + if (Avx.IsAvxSupported) { - *(long*)&r = *(long*)&input; + v128 result = Avx.undefined_ps(); + + result.Float0 = input.x; + result.Float1 = input.y; + + return result; } - else if (sizeof(T) == 6) + else if (Sse.IsSseSupported) { - *(int*)&r = *(int*)&input; - *((short*)&r + 2) = *((short*)&input + 2); + v128 result; + v128* dummyPtr = &result; + + result.Float0 = input.x; + result.Float1 = input.y; + + return result; } - else if (sizeof(T) == 4) + else throw new IllegalInstructionException(); + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(float3 input) + { + if (Avx.IsAvxSupported) { - *(int*)&r = *(int*)&input; + v128 result = Avx.undefined_ps(); + + result.Float0 = input.x; + result.Float1 = input.y; + result.Float2 = input.z; + + return result; } - else if (sizeof(T) == 3) + else if (Sse.IsSseSupported) { - *(short*)&r = *(short*)&input; - *((byte*)&r + 2) = *((byte*)&input + 2); + v128 result; + v128* dummyPtr = &result; + + result.Float0 = input.x; + result.Float1 = input.y; + result.Float2 = input.z; + + return result; } - else if (sizeof(T) == 2) + else throw new IllegalInstructionException(); + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(float4 input) + { + return new v128 + { + Float0 = input.x, + Float1 = input.y, + Float2 = input.z, + Float3 = input.w + }; + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(int input) + { + if (Avx.IsAvxSupported) { - *(short*)&r = *(short*)&input; + v128 result = Avx.undefined_si128(); + + result.SInt0 = input; + + return result; } else { - *(long*)&r = *(long*)&input; - *((long*)&r + 1) = *((long*)&input + 1); + v128 result; + v128* dummyPtr = &result; + + result.SInt0 = input; + + return result; + } + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(int2 input) + { + if (Avx.IsAvxSupported) + { + v128 result = Avx.undefined_si128(); + + result.SInt0 = input.x; + result.SInt1 = input.y; + + return result; + } + else if (Sse.IsSseSupported) + { + v128 result; + v128* dummyPtr = &result; + + result.SInt0 = input.x; + result.SInt1 = input.y; + + return result; + } + else throw new IllegalInstructionException(); + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(int3 input) + { + if (Avx.IsAvxSupported) + { + v128 result = Avx.undefined_si128(); + + result.SInt0 = input.x; + result.SInt1 = input.y; + result.SInt2 = input.z; + + return result; + } + else if (Sse.IsSseSupported) + { + v128 result; + v128* dummyPtr = &result; + + result.SInt0 = input.x; + result.SInt1 = input.y; + result.SInt2 = input.z; + + return result; + } + else throw new IllegalInstructionException(); + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(int4 input) + { + return new v128 + { + SInt0 = input.x, + SInt1 = input.y, + SInt2 = input.z, + SInt3 = input.w + }; + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(uint input) + { + if (Avx.IsAvxSupported) + { + v128 result = Avx.undefined_si128(); + + result.UInt0 = input; + + return result; + } + else + { + v128 result; + v128* dummyPtr = &result; + + result.UInt0 = input; + + return result; + } + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(uint2 input) + { + if (Avx.IsAvxSupported) + { + v128 result = Avx.undefined_si128(); + + result.UInt0 = input.x; + result.UInt1 = input.y; + + return result; + } + else if (Sse.IsSseSupported) + { + v128 result; + v128* dummyPtr = &result; + + result.UInt0 = input.x; + result.UInt1 = input.y; + + return result; + } + else throw new IllegalInstructionException(); + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(uint3 input) + { + if (Avx.IsAvxSupported) + { + v128 result = Avx.undefined_si128(); + + result.UInt0 = input.x; + result.UInt1 = input.y; + result.UInt2 = input.z; + + return result; + } + else if (Sse.IsSseSupported) + { + v128 result; + v128* dummyPtr = &result; + + result.UInt0 = input.x; + result.UInt1 = input.y; + result.UInt2 = input.z; + + return result; + } + else throw new IllegalInstructionException(); + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(uint4 input) + { + return new v128 + { + UInt0 = input.x, + UInt1 = input.y, + UInt2 = input.z, + UInt3 = input.w + }; + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(half input) + { + if (Avx.IsAvxSupported) + { + v128 result = Avx.undefined_si128(); + + result.UShort0 = input.value; + + return result; + } + else + { + v128 result; + v128* dummyPtr = &result; + + result.UShort0 = input.value; + + return result; + } + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(half2 input) + { + if (Avx.IsAvxSupported) + { + v128 result = Avx.undefined_si128(); + + result.UShort0 = input.x.value; + result.UShort1 = input.y.value; + + return result; + } + else if (Sse.IsSseSupported) + { + v128 result; + v128* dummyPtr = &result; + + result.UShort0 = input.x.value; + result.UShort1 = input.y.value; + + return result; + } + else throw new IllegalInstructionException(); + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(half3 input) + { + if (Avx.IsAvxSupported) + { + v128 result = Avx.undefined_si128(); + + result.UShort0 = input.x.value; + result.UShort1 = input.y.value; + result.UShort2 = input.z.value; + + return result; + } + else if (Sse.IsSseSupported) + { + v128 result; + v128* dummyPtr = &result; + + result.UShort0 = input.x.value; + result.UShort1 = input.y.value; + result.UShort2 = input.z.value; + + return result; + } + else throw new IllegalInstructionException(); + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(half4 input) + { + return new v128 + { + UShort0 = input.x.value, + UShort1 = input.y.value, + UShort2 = input.z.value, + UShort3 = input.w.value + }; + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(bool input) + { + if (Avx.IsAvxSupported) + { + v128 result = Avx.undefined_si128(); + + result.Byte0 = *(byte*)&input; + + return result; + } + else + { + v128 result; + v128* dummyPtr = &result; + + result.Byte0 = *(byte*)&input; + + return result; + } + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(bool2 input) + { + if (Avx.IsAvxSupported) + { + v128 result = Avx.undefined_si128(); + + result.Byte0 = maxmath.tobyte(input.x); + result.Byte1 = maxmath.tobyte(input.y); + + return result; + } + else if (Sse.IsSseSupported) + { + v128 result; + v128* dummyPtr = &result; + + result.Byte0 = maxmath.tobyte(input.x); + result.Byte1 = maxmath.tobyte(input.y); + + return result; } - - return r; + else throw new IllegalInstructionException(); } + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(bool3 input) + { + if (Avx.IsAvxSupported) + { + v128 result = Avx.undefined_si128(); + + result.Byte0 = maxmath.tobyte(input.x); + result.Byte1 = maxmath.tobyte(input.y); + result.Byte2 = maxmath.tobyte(input.z); + + return result; + } + else if (Sse.IsSseSupported) + { + v128 result; + v128* dummyPtr = &result; + result.Byte0 = maxmath.tobyte(input.x); + result.Byte1 = maxmath.tobyte(input.y); + result.Byte2 = maxmath.tobyte(input.z); + + return result; + } + else throw new IllegalInstructionException(); + } + [SkipLocalsInit] [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static T ToType(v256 input) - where T : unmanaged + internal static v128 ToV128(bool4 input) { - if (sizeof(T) == sizeof(v256)) + if (Avx.IsAvxSupported) { - return *(T*)&input; + v128 result = Avx.undefined_si128(); + + result.Byte0 = maxmath.tobyte(input.x); + result.Byte1 = maxmath.tobyte(input.y); + result.Byte2 = maxmath.tobyte(input.z); + result.Byte3 = maxmath.tobyte(input.w); + + return result; + } + else if (Sse.IsSseSupported) + { + v128 result; + v128* dummyPtr = &result; + + result.Byte0 = maxmath.tobyte(input.x); + result.Byte1 = maxmath.tobyte(input.y); + result.Byte2 = maxmath.tobyte(input.z); + result.Byte3 = maxmath.tobyte(input.w); + + return result; + } + else throw new IllegalInstructionException(); + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(byte input) + { + if (Avx.IsAvxSupported) + { + v128 result = Avx.undefined_si128(); + + result.Byte0 = input; + + return result; } else { - T r; - *(v128*)&r = *(v128*)&input; - *((long*)&r + 2) = *((long*)&input + 2); - - return r; + v128 result; + v128* dummyPtr = &result; + + result.Byte0 = input; + + return result; } } [SkipLocalsInit] [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static T ToType(v128 input) - where T : unmanaged + internal static v128 ToV128(sbyte input) { - T r; + if (Avx.IsAvxSupported) + { + v128 result = Avx.undefined_si128(); + + result.SByte0 = input; - if (sizeof(T) == sizeof(v128)) + return result; + } + else + { + v128 result; + v128* dummyPtr = &result; + + result.SByte0 = input; + + return result; + } + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(ushort input) + { + if (Avx.IsAvxSupported) { - return *(T*)&input; + v128 result = Avx.undefined_si128(); + + result.UShort0 = input; + + return result; } - else if (sizeof(T) == 12) + else { - *(long*)&r = input.SLong0; - *((int*)&r + 2) = input.SInt2; + v128 result; + v128* dummyPtr = &result; + + result.UShort0 = input; + + return result; } - else if (sizeof(T) == 8) + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(short input) + { + if (Avx.IsAvxSupported) { - *(long*)&r = input.SLong0; + v128 result = Avx.undefined_si128(); + + result.SShort0 = input; + + return result; } - else if (sizeof(T) == 6) + else { - *(int*)&r = input.SInt0; - *((short*)&r + 2) = input.SShort2; + v128 result; + v128* dummyPtr = &result; + + result.SShort0 = input; + + return result; } - else if (sizeof(T) == 4) + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(ulong input) + { + if (Avx.IsAvxSupported) { - *(int*)&r = input.SInt0; + v128 result = Avx.undefined_si128(); + + result.ULong0 = input; + + return result; } - else if (sizeof(T) == 3) + else { - *(short*)&r = input.SShort0; - *((byte*)&r + 2) = input.Byte2; + v128 result; + v128* dummyPtr = &result; + + result.ULong0 = input; + + return result; } - else if (sizeof(T) == 2) + } + + [SkipLocalsInit] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ToV128(long input) + { + if (Avx.IsAvxSupported) { - *(short*)&r = input.SShort0; - } + v128 result = Avx.undefined_si128(); + + result.SLong0 = input; + + return result; + } else { - *(long*)&r = input.SLong0; - *((long*)&r + 1) = input.SLong1; + v128 result; + v128* dummyPtr = &result; + + result.SLong0 = input; + + return result; } + } + - return r; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static half ToHalf(v128 input) + { + return maxmath.ashalf(input.UShort0); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static half2 ToHalf2(v128 input) + { + return new half2(maxmath.ashalf(input.UShort0), maxmath.ashalf(input.UShort1)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static half3 ToHalf3(v128 input) + { + return new half3(maxmath.ashalf(input.UShort0), maxmath.ashalf(input.UShort1), maxmath.ashalf(input.UShort2)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static half4 ToHalf4(v128 input) + { + return new half4(maxmath.ashalf(input.UShort0), maxmath.ashalf(input.UShort1), maxmath.ashalf(input.UShort2), maxmath.ashalf(input.UShort3)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static float ToFloat(v128 input) + { + return input.Float0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static float2 ToFloat2(v128 input) + { + return new float2(input.Float0, input.Float1); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static float3 ToFloat3(v128 input) + { + return new float3(input.Float0, input.Float1, input.Float2); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static float4 ToFloat4(v128 input) + { + return new float4(input.Float0, input.Float1, input.Float2, input.Float3); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static double ToDouble(v128 input) + { + return input.Double0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static double2 ToDouble2(v128 input) + { + return new double2(input.Double0, input.Double1); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static double3 ToDouble3(v256 input) + { + return new double3(input.Double0, input.Double1, input.Double2); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static double4 ToDouble4(v256 input) + { + return new double4(input.Double0, input.Double1, input.Double2, input.Double3); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int ToInt(v128 input) + { + return input.SInt0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int2 ToInt2(v128 input) + { + return new int2(input.SInt0, input.SInt1); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int3 ToInt3(v128 input) + { + return new int3(input.SInt0, input.SInt1, input.SInt2); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int4 ToInt4(v128 input) + { + return new int4(input.SInt0, input.SInt1, input.SInt2, input.SInt3); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static uint ToUInt(v128 input) + { + return input.UInt0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static uint2 ToUInt2(v128 input) + { + return new uint2(input.UInt0, input.UInt1); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static uint3 ToUInt3(v128 input) + { + return new uint3(input.UInt0, input.UInt1, input.UInt2); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static uint4 ToUInt4(v128 input) + { + return new uint4(input.UInt0, input.UInt1, input.UInt2, input.UInt3); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static byte ToByte(v128 input) + { + return input.Byte0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static sbyte ToSByte(v128 input) + { + return input.SByte0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ushort ToUShort(v128 input) + { + return input.UShort0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static short ToShort(v128 input) + { + return input.SShort0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ulong ToULong(v128 input) + { + return input.ULong0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static long ToLong(v128 input) + { + return input.SLong0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool ToBool(v128 input) + { + return maxmath.tobool(input.Byte0); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool2 ToBool2(v128 input) + { + return new bool2(maxmath.tobool(input.Byte0), maxmath.tobool(input.Byte1)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool3 ToBool3(v128 input) + { + return new bool3(maxmath.tobool(input.Byte0), maxmath.tobool(input.Byte1), maxmath.tobool(input.Byte2)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool4 ToBool4(v128 input) + { + return new bool4(maxmath.tobool(input.Byte0), maxmath.tobool(input.Byte1), maxmath.tobool(input.Byte2), maxmath.tobool(input.Byte3)); } } } diff --git a/Runtime/__Internal/Shuffle/(S)Byte234.cs b/Runtime/__Internal/Shuffle/(S)Byte234.cs index e927133..779da1e 100644 --- a/Runtime/__Internal/Shuffle/(S)Byte234.cs +++ b/Runtime/__Internal/Shuffle/(S)Byte234.cs @@ -1,5479 +1,5582 @@ -using System.Runtime.CompilerServices; -using Unity.Mathematics; -using Unity.Burst.Intrinsics; - -using static Unity.Burst.Intrinsics.X86; - -namespace MaxMath -{ - unsafe internal static partial class Shuffle - { - internal static partial class Bytes - { - internal static partial class Get - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxxx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, Sse2.setzero_si128()); - } - else if (Sse2.IsSse2Supported) - { - v128 _xxyy = Sse2.unpacklo_epi8(x, x); - - return Sse2.unpacklo_epi16(_xxyy, _xxyy); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxxy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyy = Sse2.unpacklo_epi8(x, x); - - return Sse2.unpacklo_epi16(xxyy, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxxz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 xxxxzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 2, 0, 0)); - - return Sse2.bsrli_si128(xxxxzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 xxxxww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 0, 0)); - - return Sse2.bsrli_si128(xxxxww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxyx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xx = Sse2.unpacklo_epi8(x, x); - - return Sse2.unpacklo_epi8(x, xx); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxyy(v128 x) - { - if (Sse2.IsSse2Supported) - { - return Sse2.unpacklo_epi8(x, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxyz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_x_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 1, 0, 0)); - - return Sse2.packus_epi16(x_x_y_z, x_x_y_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_x_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 0, 0)); - - return Sse2.packus_epi16(x_x_y_w, x_x_y_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxzx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_x_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 0, 0)); - - return Sse2.packus_epi16(x_x_z_x, x_x_z_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxzy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - v128 xz = Sse2.unpacklo_epi8(x, z); - - return Sse2.unpacklo_epi8(xz, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxzz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 0)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_x_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 0, 0)); - - return Sse2.packus_epi16(x_x_z_w, x_x_z_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxwx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_x_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 0, 0)); - - return Sse2.packus_epi16(x_x_w_x, x_x_w_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxwy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_x_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 0, 0)); - - return Sse2.packus_epi16(x_x_w_y, x_x_w_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxwz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_x_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 0, 0)); - - return Sse2.packus_epi16(x_x_w_z, x_x_w_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 0)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xyxx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 _xxyy = Sse2.unpacklo_epi8(x, x); - - return Sse2.unpacklo_epi16(x, _xxyy); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xyxy(v128 x) - { - if (Sse2.IsSse2Supported) - { - return Sse2.shufflelo_epi16(x, Sse.SHUFFLE(0, 0, 0, 0)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xyxz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - v128 xz = Sse2.unpacklo_epi8(x, z); - - return Sse2.unpacklo_epi16(x, xz); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xyxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_y_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 1, 0)); - - return Sse2.packus_epi16(x_y_x_w, x_y_x_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xyyx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 y = Sse2.bsrli_si128(x, sizeof(byte)); - v128 yx = Sse2.unpacklo_epi8(y, x); - - return Sse2.unpacklo_epi16(x, yx); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xyyy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 xxyyyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 1, 1, 0)); - - return Sse2.bsrli_si128(xxyyyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xyyz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); - - return Sse2.unpacklo_epi8(x, yz); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xyyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 xxyyww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 1, 0)); - - return Sse2.bsrli_si128(xxyyww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xyzx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 _xyz = Sse2.bslli_si128(x, sizeof(byte)); - v128 _xyzx = Sse2.unpacklo_epi32(_xyz, x); - - return Sse2.bsrli_si128(_xyzx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xyzy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_y_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 2, 1, 0)); - - return Sse2.packus_epi16(x_y_z_y, x_y_z_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xyzz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - v128 zz = Sse2.unpacklo_epi8(z, z); - - return Sse2.unpacklo_epi16(x, zz); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xywx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_y_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 1, 0)); - - return Sse2.packus_epi16(x_y_w_x, x_y_w_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xywy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_y_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 1, 0)); - - return Sse2.packus_epi16(x_y_w_y, x_y_w_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xywz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 1, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_y_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 1, 0)); - - return Sse2.packus_epi16(x_y_w_z, x_y_w_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xyww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_y_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 1, 0)); - - return Sse2.packus_epi16(x_y_w_w, x_y_w_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzxx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_z_x_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 2, 0)); - - return Sse2.packus_epi16(x_z_x_x, x_z_x_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzxy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - v128 xz = Sse2.unpacklo_epi8(x, z); - - return Sse2.unpacklo_epi16(xz, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzxz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - v128 xz = Sse2.unpacklo_epi8(x, z); - - return Sse2.unpacklo_epi16(xz, xz); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_z_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 2, 0)); - - return Sse2.packus_epi16(x_z_x_w, x_z_x_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzyx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - v128 zx = Sse2.unpacklo_epi8(z, x); - - return Sse2.unpacklo_epi8(x, zx); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzyy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_z_y_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 1, 2, 0)); - - return Sse2.packus_epi16(x_z_y_y, x_z_y_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzyz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - v128 zz = Sse2.unpacklo_epi8(z, z); - - return Sse2.unpacklo_epi8(x, zz); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - - return Sse2.unpacklo_epi8(x, zw); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzzx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 xxzzxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 0)); - - return Sse2.bsrli_si128(xxzzxx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzzy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 xxzzyy = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 1, 2, 0)); - - return Sse2.bsrli_si128(xxzzyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzzz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 xxzzzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 2, 2, 0)); - - return Sse2.bsrli_si128(xxzzzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 xxzzww = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 3, 2, 0)); - - return Sse2.bsrli_si128(xxzzww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzwx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_z_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 2, 0)); - - return Sse2.packus_epi16(x_z_w_x, x_z_w_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzwy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_z_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 2, 0)); - - return Sse2.packus_epi16(x_z_w_y, x_z_w_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzwz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_z_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 2, 0)); - - return Sse2.packus_epi16(x_z_w_z, x_z_w_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_z_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 2, 0)); - - return Sse2.packus_epi16(x_z_w_w, x_z_w_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwxx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_w_x_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 3, 0)); - - return Sse2.packus_epi16(x_w_x_x, x_w_x_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwxy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_w_x_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 0, 3, 0)); - - return Sse2.packus_epi16(x_w_x_y, x_w_x_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwxz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_w_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 3, 0)); - - return Sse2.packus_epi16(x_w_x_z, x_w_x_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_w_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 3, 0)); - - return Sse2.packus_epi16(x_w_x_w, x_w_x_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwyx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_w_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 3, 0)); - - return Sse2.packus_epi16(x_w_y_x, x_w_y_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwyy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_w_y_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 1, 3, 0)); - - return Sse2.packus_epi16(x_w_y_y, x_w_y_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwyz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_w_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 1, 3, 0)); - - return Sse2.packus_epi16(x_w_y_z, x_w_y_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_w_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 3, 0)); - - return Sse2.packus_epi16(x_w_y_w, x_w_y_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwzx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_w_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 3, 0)); - - return Sse2.packus_epi16(x_w_z_x, x_w_z_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwzy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_w_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 2, 3, 0)); - - return Sse2.packus_epi16(x_w_z_y, x_w_z_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwzz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_w_z_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 2, 3, 0)); - - return Sse2.packus_epi16(x_w_z_z, x_w_z_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_w_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 3, 0)); - - return Sse2.packus_epi16(x_w_z_w, x_w_z_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwwx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 xxwwxx = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 0)); - - return Sse2.bsrli_si128(xxwwxx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwwy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 xxwwyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 1, 3, 0)); - - return Sse2.bsrli_si128(xxwwyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwwz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 xxwwzz = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 2, 3, 0)); - - return Sse2.bsrli_si128(xxwwzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 xxwwww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 3, 0)); - - return Sse2.bsrli_si128(xxwwww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxxx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 yyxxxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 0, 1)); - - return Sse2.bsrli_si128(yyxxxx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxxy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 y = Sse2.bsrli_si128(x, sizeof(byte)); - v128 yx = Sse2.unpacklo_epi8(y, x); - - return Sse2.unpacklo_epi16(yx, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxxz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 yyxxzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 2, 0, 1)); - - return Sse2.bsrli_si128(yyxxzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 yyxxww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 0, 1)); - - return Sse2.bsrli_si128(yyxxww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxyx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 y = Sse2.bsrli_si128(x, sizeof(byte)); - v128 yx = Sse2.unpacklo_epi8(y, x); - - return Sse2.unpacklo_epi16(yx, yx); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxyy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 y = Sse2.bsrli_si128(x, sizeof(byte)); - v128 yy = Sse2.unpacklo_epi8(y, y); - - return Sse2.unpacklo_epi8(yy, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxyz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); - v128 yx = Sse2.unpacklo_epi8(yz, x); - - return Sse2.unpacklo_epi16(yx, yz); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_x_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 0, 1)); - - return Sse2.packus_epi16(y_x_y_w, y_x_y_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxzx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); - v128 xx = Sse2.unpacklo_epi8(x, x); - - return Sse2.unpacklo_epi8(yz, xx); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxzy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); - - return Sse2.unpacklo_epi8(yz, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxzz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_x_z_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 2, 0, 1)); - - return Sse2.packus_epi16(y_x_z_z, y_x_z_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_x_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 0, 1)); - - return Sse2.packus_epi16(y_x_z_w, y_x_z_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxwx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_x_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 0, 1)); - - return Sse2.packus_epi16(y_x_w_x, y_x_w_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxwy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_x_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 0, 1)); - - return Sse2.packus_epi16(y_x_w_y, y_x_w_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxwz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_x_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 0, 1)); - - return Sse2.packus_epi16(y_x_w_z, y_x_w_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_x_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 0, 1)); - - return Sse2.packus_epi16(y_x_w_w, y_x_w_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyxx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyy = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyy, Sse.SHUFFLE(0, 1, 0, 1)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyxy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 y = Sse2.bsrli_si128(x, sizeof(byte)); - v128 yy = Sse2.unpacklo_epi8(y, y); - - return Sse2.unpacklo_epi16(yy, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyxz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); - v128 yx = Sse2.unpacklo_epi8(yz, x); - - return Sse2.unpacklo_epi8(yx, yz); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_y_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 1, 1)); - - return Sse2.packus_epi16(y_y_x_w, y_y_x_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyyx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 yyyyxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 1, 1)); - - return Sse2.bsrli_si128(yyyyxx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyyy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(1, 1, 1, 1)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyyz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 yyyyzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 2, 1, 1)); - - return Sse2.bsrli_si128(yyyyzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 yyyyww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 1, 1)); - - return Sse2.bsrli_si128(yyyyww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyzx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_y_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 1, 1)); - - return Sse2.packus_epi16(y_y_z_x, y_y_z_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyzy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); - v128 yy = Sse2.unpacklo_epi8(yz, yz); - - return Sse2.unpacklo_epi8(yz, yy); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyzz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 1)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_y_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 1, 1)); - - return Sse2.packus_epi16(y_y_z_w, y_y_z_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yywx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_y_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 1, 1)); - - return Sse2.packus_epi16(y_y_w_x, y_y_w_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yywy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_y_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 1, 1)); - - return Sse2.packus_epi16(y_y_w_y, y_y_w_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yywz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_y_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 1, 1)); - - return Sse2.packus_epi16(y_y_w_z, y_y_w_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 3, 1)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzxx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); - v128 xx = Sse2.unpacklo_epi8(x, x); - - return Sse2.unpacklo_epi16(yz, xx); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzxy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); - - return Sse2.unpacklo_epi16(yz, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzxz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_z_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 2, 1)); - - return Sse2.packus_epi16(y_z_x_z, y_z_x_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_z_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 2, 1)); - - return Sse2.packus_epi16(y_z_x_w, y_z_x_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzyx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); - v128 yx = Sse2.unpacklo_epi8(yz, x); - - return Sse2.unpacklo_epi16(yz, yx); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzyy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); - v128 yy = Sse2.unpacklo_epi8(yz, yz); - - return Sse2.unpacklo_epi16(yz, yy); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzyz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); - - return Sse2.unpacklo_epi16(yz, yz); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_z_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 2, 1)); - - return Sse2.packus_epi16(y_z_y_w, y_z_y_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzzx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 yyzzxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 1)); - - return Sse2.bsrli_si128(yyzzxx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzzy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 yyzzyy = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 1, 2, 1)); - - return Sse2.bsrli_si128(yyzzyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzzz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 yyzzzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 2, 2, 1)); - - return Sse2.bsrli_si128(yyzzzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_z_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 2, 1)); - - return Sse2.packus_epi16(y_z_z_w, y_z_z_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzwx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - int yzwx = math.ror(Sse2.cvtsi128_si32(x), 8); - - return Sse2.cvtsi32_si128(yzwx); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzwy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_z_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 2, 1)); - - return Sse2.packus_epi16(y_z_w_y, y_z_w_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzwz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_z_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 2, 1)); - - return Sse2.packus_epi16(y_z_w_z, y_z_w_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_z_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 2, 1)); - - return Sse2.packus_epi16(y_z_w_w, y_z_w_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywxx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_w_x_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 3, 1)); - - return Sse2.packus_epi16(y_w_x_x, y_w_x_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywxy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_w_x_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 0, 3, 1)); - - return Sse2.packus_epi16(y_w_x_y, y_w_x_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywxz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_w_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 3, 1)); - - return Sse2.packus_epi16(y_w_x_z, y_w_x_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_w_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 3, 1)); - - return Sse2.packus_epi16(y_w_x_w, y_w_x_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywyx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_w_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 3, 1)); - - return Sse2.packus_epi16(y_w_y_x, y_w_y_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywyy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_w_y_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 1, 3, 1)); - - return Sse2.packus_epi16(y_w_y_y, y_w_y_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywyz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_w_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 1, 3, 1)); - - return Sse2.packus_epi16(y_w_y_z, y_w_y_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_w_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 3, 1)); - - return Sse2.packus_epi16(y_w_y_w, y_w_y_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywzx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_w_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 3, 1)); - - return Sse2.packus_epi16(y_w_z_x, y_w_z_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywzy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_w_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 2, 3, 1)); - - return Sse2.packus_epi16(y_w_z_y, y_w_z_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywzz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_w_z_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 2, 3, 1)); - - return Sse2.packus_epi16(y_w_z_z, y_w_z_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_w_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 3, 1)); - - return Sse2.packus_epi16(y_w_z_w, y_w_z_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywwx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 yywwxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 3, 1)); - - return Sse2.bsrli_si128(yywwxx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywwy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 yywwyy = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 1, 3, 1)); - - return Sse2.bsrli_si128(yywwyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywwz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 yywwzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 2, 3, 1)); - - return Sse2.bsrli_si128(yywwzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 yywwww = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 3, 3, 1)); - - return Sse2.bsrli_si128(yywwww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxxx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 zzxxxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 0, 2)); - - return Sse2.bsrli_si128(zzxxxx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxxy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 zzxxyy = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 1, 0, 2)); - - return Sse2.bsrli_si128(zzxxyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxxz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 zzxxzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 2, 0, 2)); - - return Sse2.bsrli_si128(zzxxzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 zzxxww = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 3, 0, 2)); - - return Sse2.bsrli_si128(zzxxww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxyx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_x_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 0, 2)); - - return Sse2.packus_epi16(z_x_y_x, z_x_y_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxyy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_x_y_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 1, 0, 2)); - - return Sse2.packus_epi16(z_x_y_y, z_x_y_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxyz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_x_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 1, 0, 2)); - - return Sse2.packus_epi16(z_x_y_z, z_x_y_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_x_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 0, 2)); - - return Sse2.packus_epi16(z_x_y_w, z_x_y_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxzx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_x_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 0, 2)); - - return Sse2.packus_epi16(z_x_z_x, z_x_z_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxzy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - v128 zz = Sse2.unpacklo_epi8(z, z); - - return Sse2.unpacklo_epi8(zz, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxzz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_x_z_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 2, 0, 2)); - - return Sse2.packus_epi16(z_x_z_z, z_x_z_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_x_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 0, 2)); - - return Sse2.packus_epi16(z_x_z_w, z_x_z_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxwx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_x_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 0, 2)); - - return Sse2.packus_epi16(z_x_w_x, z_x_w_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxwy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_x_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 0, 2)); - - return Sse2.packus_epi16(z_x_w_y, z_x_w_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxwz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_x_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 0, 2)); - - return Sse2.packus_epi16(z_x_w_z, z_x_w_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_x_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 0, 2)); - - return Sse2.packus_epi16(z_x_w_w, z_x_w_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyxx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_y_x_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 1, 2)); - - return Sse2.packus_epi16(z_y_x_x, z_y_x_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyxy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_y_x_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 0, 1, 2)); - - return Sse2.packus_epi16(z_y_x_y, z_y_x_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyxz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_y_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 1, 2)); - - return Sse2.packus_epi16(z_y_x_z, z_y_x_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_y_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 1, 2)); - - return Sse2.packus_epi16(z_y_x_w, z_y_x_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyyx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 zzyyxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 1, 2)); - - return Sse2.bsrli_si128(zzyyxx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyyy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 zzyyyy = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 1, 1, 2)); - - return Sse2.bsrli_si128(zzyyyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyyz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 zzyyzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 2, 1, 2)); - - return Sse2.bsrli_si128(zzyyzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 zzyyww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 1, 2)); - - return Sse2.bsrli_si128(zzyyww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyzx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_y_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 1, 2)); - - return Sse2.packus_epi16(z_y_z_x, z_y_z_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyzy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_y_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 2, 1, 2)); - - return Sse2.packus_epi16(z_y_z_y, z_y_z_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyzz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_y_z_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 2, 1, 2)); - - return Sse2.packus_epi16(z_y_z_z, z_y_z_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_y_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 1, 2)); - - return Sse2.packus_epi16(z_y_z_w, z_y_z_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zywx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_y_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 1, 2)); - - return Sse2.packus_epi16(z_y_w_x, z_y_w_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zywy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_y_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 1, 2)); - - return Sse2.packus_epi16(z_y_w_y, z_y_w_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zywz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_y_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 1, 2)); - - return Sse2.packus_epi16(z_y_w_z, z_y_w_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_y_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 1, 2)); - - return Sse2.packus_epi16(z_y_w_w, z_y_w_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzxx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 0, 2)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzxy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - v128 zz = Sse2.unpacklo_epi8(z, z); - - return Sse2.unpacklo_epi16(zz, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzxz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_z_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 2, 2)); - - return Sse2.packus_epi16(z_z_x_z, z_z_x_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_z_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 2, 2)); - - return Sse2.packus_epi16(z_z_x_w, z_z_x_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzyx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_z_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 2, 2)); - - return Sse2.packus_epi16(z_z_y_x, z_z_y_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzyy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 1, 2)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzyz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_z_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 1, 2, 2)); - - return Sse2.packus_epi16(z_z_y_z, z_z_y_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_z_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 2, 2)); - - return Sse2.packus_epi16(z_z_y_w, z_z_y_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzzx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 zzzzxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 2)); - - return Sse2.bsrli_si128(zzzzxx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzzy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 zzzzyy = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 1, 2, 2)); - - return Sse2.bsrli_si128(zzzzyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzzz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 2)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 zzzzww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 2, 2)); - - return Sse2.bsrli_si128(zzzzww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzwx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_z_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 2, 2)); - - return Sse2.packus_epi16(z_z_w_x, z_z_w_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzwy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_z_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 2, 2)); - - return Sse2.packus_epi16(z_z_w_y, z_z_w_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzwz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_z_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 2, 2)); - - return Sse2.packus_epi16(z_z_w_z, z_z_w_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 2)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwxx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_w_x_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 3, 2)); - - return Sse2.packus_epi16(z_w_x_x, z_w_x_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwxy(v128 x) - { - if (Sse2.IsSse2Supported) - { - return Sse2.shufflelo_epi16(x, Sse.SHUFFLE(3, 3, 0, 1)); - } - else if (Sse2.IsSse2Supported) - { - v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - - return Sse2.unpacklo_epi16(zw, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwxz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_w_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 3, 2)); - - return Sse2.packus_epi16(z_w_x_z, z_w_x_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_w_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 3, 2)); - - return Sse2.packus_epi16(z_w_x_w, z_w_x_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwyx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_w_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 3, 2)); - - return Sse2.packus_epi16(z_w_y_x, z_w_y_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwyy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_w_y_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 1, 3, 2)); - - return Sse2.packus_epi16(z_w_y_y, z_w_y_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwyz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_w_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 1, 3, 2)); - - return Sse2.packus_epi16(z_w_y_z, z_w_y_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_w_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 3, 2)); - - return Sse2.packus_epi16(z_w_y_w, z_w_y_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwzx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_w_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 3, 2)); - - return Sse2.packus_epi16(z_w_z_x, z_w_z_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwzy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_w_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 2, 3, 2)); - - return Sse2.packus_epi16(z_w_z_y, z_w_z_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwzz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_w_z_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 2, 3, 2)); - - return Sse2.packus_epi16(z_w_z_z, z_w_z_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwzw(v128 x) - { - if (Sse2.IsSse2Supported) - { - return Sse2.shufflelo_epi16(x, Sse.SHUFFLE(3, 3, 1, 1)); - } - else if (Sse2.IsSse2Supported) - { - v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - - return Sse2.unpacklo_epi16(zw, zw); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwwx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 zzwwxx = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 2)); - - return Sse2.bsrli_si128(zzwwxx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwwy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 zzwwyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 1, 3, 2)); - - return Sse2.bsrli_si128(zzwwyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwwz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 zzwwzz = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 2, 3, 2)); - - return Sse2.bsrli_si128(zzwwzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 zzwwww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 3, 2)); - - return Sse2.bsrli_si128(zzwwww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxxx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwxxxx = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 0, 3)); - - return Sse2.bsrli_si128(wwxxxx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxxy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwxxyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 1, 0, 3)); - - return Sse2.bsrli_si128(wwxxyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxxz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwxxzz = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 2, 0, 3)); - - return Sse2.bsrli_si128(wwxxzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwxxww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 0, 3)); - - return Sse2.bsrli_si128(wwxxww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxyx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_x_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 0, 3)); - - return Sse2.packus_epi16(w_x_y_x, w_x_y_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxyy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_x_y_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 1, 0, 3)); - - return Sse2.packus_epi16(w_x_y_y, w_x_y_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxyz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - int wxyz = math.rol(Sse2.cvtsi128_si32(x), 8); - - return Sse2.cvtsi32_si128(wxyz); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_x_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 0, 3)); - - return Sse2.packus_epi16(w_x_y_w, w_x_y_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxzx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_x_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 0, 3)); - - return Sse2.packus_epi16(w_x_z_x, w_x_z_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxzy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_x_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 2, 0, 3)); - - return Sse2.packus_epi16(w_x_z_y, w_x_z_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxzz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_x_z_t = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 2, 0, 3)); - - return Sse2.packus_epi16(w_x_z_t, w_x_z_t); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_x_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 0, 3)); - - return Sse2.packus_epi16(w_x_z_w, w_x_z_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxwx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_x_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 0, 3)); - - return Sse2.packus_epi16(w_x_w_x, w_x_w_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxwy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_x_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 0, 3)); - - return Sse2.packus_epi16(w_x_w_y, w_x_w_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxwz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_x_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 0, 3)); - - return Sse2.packus_epi16(w_x_w_z, w_x_w_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_x_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 0, 3)); - - return Sse2.packus_epi16(w_x_w_w, w_x_w_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyxx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_y_x_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 1, 3)); - - return Sse2.packus_epi16(w_y_x_x, w_y_x_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyxy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_y_x_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 0, 1, 3)); - - return Sse2.packus_epi16(w_y_x_y, w_y_x_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyxz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_y_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 1, 3)); - - return Sse2.packus_epi16(w_y_x_z, w_y_x_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_y_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 1, 3)); - - return Sse2.packus_epi16(w_y_x_w, w_y_x_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyyx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwyyxx = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 1, 3)); - - return Sse2.bsrli_si128(wwyyxx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyyy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwyyyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 1, 1, 3)); - - return Sse2.bsrli_si128(wwyyyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyyz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwyyzz = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 2, 1, 3)); - - return Sse2.bsrli_si128(wwyyzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 wwyyww = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 3, 1, 3)); - - return Sse2.bsrli_si128(wwyyww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyzx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_y_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 1, 3)); - - return Sse2.packus_epi16(w_y_z_x, w_y_z_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyzy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_y_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 2, 1, 3)); - - return Sse2.packus_epi16(w_y_z_y, w_y_z_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyzz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_y_z_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 2, 1, 3)); - - return Sse2.packus_epi16(w_y_z_z, w_y_z_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_y_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 1, 3)); - - return Sse2.packus_epi16(w_y_z_w, w_y_z_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wywx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_y_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 1, 3)); - - return Sse2.packus_epi16(w_y_w_x, w_y_w_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wywy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_y_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 1, 3)); - - return Sse2.packus_epi16(w_y_w_y, w_y_w_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wywz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_y_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 1, 3)); - - return Sse2.packus_epi16(w_y_w_z, w_y_w_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_y_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 1, 3)); - - return Sse2.packus_epi16(w_y_w_w, w_y_w_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzxx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_z_x_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 2, 3)); - - return Sse2.packus_epi16(w_z_x_x, w_z_x_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzxy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_z_x_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 0, 2, 3)); - - return Sse2.packus_epi16(w_z_x_y, w_z_x_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzxz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_z_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 2, 3)); - - return Sse2.packus_epi16(w_z_x_z, w_z_x_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_z_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 2, 3)); - - return Sse2.packus_epi16(w_z_x_w, w_z_x_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzyx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - int wzyx = maxmath.reversebytes(Sse2.cvtsi128_si32(x)); - - return Sse2.cvtsi32_si128(wzyx); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzyy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_z_y_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 1, 2, 3)); - - return Sse2.packus_epi16(w_z_y_y, w_z_y_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzyz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_z_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 1, 2, 3)); - - return Sse2.packus_epi16(w_z_y_z, w_z_y_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_z_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 2, 3)); - - return Sse2.packus_epi16(w_z_y_w, w_z_y_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzzx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwzzxx = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 2, 3)); - - return Sse2.bsrli_si128(wwzzxx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzzy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwzzyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 1, 2, 3)); - - return Sse2.bsrli_si128(wwzzyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzzz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwzzzz = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 2, 2, 3)); - - return Sse2.bsrli_si128(wwzzzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwzzww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 2, 3)); - - return Sse2.bsrli_si128(wwzzww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzwx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_z_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 2, 3)); - - return Sse2.packus_epi16(w_z_w_x, w_z_w_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzwy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_z_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 2, 3)); - - return Sse2.packus_epi16(w_z_w_y, w_z_w_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzwz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_z_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 2, 3)); - - return Sse2.packus_epi16(w_z_w_z, w_z_w_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_z_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 2, 3)); - - return Sse2.packus_epi16(w_z_w_w, w_z_w_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwxx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 0, 3)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwxy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 ww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 0, 3)); - - return Sse2.unpacklo_epi16(ww, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwxz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_w_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 3, 3)); - - return Sse2.packus_epi16(w_w_x_z, w_w_x_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_w_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 3, 3)); - - return Sse2.packus_epi16(w_w_x_w, w_w_x_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwyx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_w_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 3, 3)); - - return Sse2.packus_epi16(w_w_y_x, w_w_y_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwyy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 1, 3)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwyz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_w_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 1, 3, 3)); - - return Sse2.packus_epi16(w_w_y_z, w_w_y_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_w_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 3, 3)); - - return Sse2.packus_epi16(w_w_y_w, w_w_y_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwzx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_w_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 3, 3)); - - return Sse2.packus_epi16(w_w_z_x, w_w_z_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwzy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_w_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 2, 3, 3)); - - return Sse2.packus_epi16(w_w_z_y, w_w_z_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwzz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 2, 3)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_w_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 3, 3)); - - return Sse2.packus_epi16(w_w_z_w, w_w_z_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwwx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwwwxx = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 3)); - - return Sse2.bsrli_si128(wwwwxx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwwy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwwwyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 1, 3, 3)); - - return Sse2.bsrli_si128(wwwwyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwwz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwwwzz = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 2, 3, 3)); - - return Sse2.bsrli_si128(wwwwzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 3)); - } - else throw new IllegalInstructionException(); - } - - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, Sse2.setzero_si128()); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyy = Sse2.unpacklo_epi8(x, x); - - return Sse2.unpacklo_epi16(xxyy, xxyy); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxy(v128 x) - { if (Sse2.IsSse2Supported) - { - return Sse2.unpacklo_epi8(x, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 0)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 0)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xyx(v128 x) - { if (Sse2.IsSse2Supported) - { - return Sse2.shufflelo_epi16(x, Sse.SHUFFLE(0, 0, 0, 0)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xyy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyy = Sse2.unpacklo_epi8(x, x); - - return Sse2.bsrli_si128(xxyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xyz(v128 x) - { - if (Sse2.IsSse2Supported) - { - return (v128)x; - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 w = Sse2.bsrli_si128(x, 3 * sizeof(byte)); - - return Sse2.unpacklo_epi16(x, w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - v128 xz = Sse2.unpacklo_epi8(x, z); - - return Sse2.unpacklo_epi16(xz, xz); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 2, 0)); - - return Sse2.packus_epi16(x_z_y, x_z_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 xxzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 0)); - - return Sse2.bsrli_si128(xxzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 2, 0)); - - return Sse2.packus_epi16(x_z_w, x_z_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 w = Sse2.bsrli_si128(x, 3 * sizeof(byte)); - v128 xx = Sse2.unpacklo_epi8(x, x); - - return Sse2.unpacklo_epi8(xx, w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 w = Sse2.bsrli_si128(x, 3 * sizeof(byte)); - - return Sse2.unpacklo_epi8(x, w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xwz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 x_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 3, 0)); - - return Sse2.packus_epi16(x_w_z, x_w_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 xxww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 0)); - - return Sse2.bsrli_si128(xxww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 y = Sse2.bsrli_si128(x, sizeof(byte)); - v128 yx = Sse2.unpacklo_epi8(y, x); - - return Sse2.unpacklo_epi16(yx, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xyxy = Sse2.shufflelo_epi16(x, Sse.SHUFFLE(0, 0, 0, 0)); - - return Sse2.bsrli_si128(xyxy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 0, 1)); - - return Sse2.packus_epi16(y_x_z, y_x_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 0, 1)); - - return Sse2.packus_epi16(y_x_w, y_x_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyy = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyy, Sse.SHUFFLE(0, 0, 0, 1)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyy = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyy, Sse.SHUFFLE(1, 1, 1, 1)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 2, 1)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 1)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); - - return Sse2.unpacklo_epi16(yz, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); - - return Sse2.unpacklo_epi16(yz, yz); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - - return Sse2.bsrli_si128(xxyyzz, 3 * sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yzw(v128 x) - { - if (Sse2.IsSse2Supported) - { - return Sse2.bsrli_si128(x, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 3, 1)); - - return Sse2.packus_epi16(y_w_x, y_w_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 y_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 3, 1)); - - return Sse2.packus_epi16(y_w_y, y_w_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ywz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); - v128 w = Sse2.bsrli_si128(x, 3 * sizeof(byte)); - - return Sse2.unpacklo_epi8(yz, w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 yyww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 1)); - - return Sse2.bsrli_si128(yyww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 zzxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 0, 2)); - - return Sse2.bsrli_si128(zzxx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_x_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 0, 2)); - - return Sse2.packus_epi16(z_x_y, z_x_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 0, 2)); - - return Sse2.packus_epi16(z_x_z, z_x_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - - return Sse2.unpacklo_epi8(zw, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 1, 2)); - - return Sse2.packus_epi16(z_y_x, z_y_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - v128 zzyy = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 1, 2)); - - return Sse2.bsrli_si128(zzyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 z_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 1, 2)); - - return Sse2.packus_epi16(z_y_z, z_y_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 y = Sse2.bsrli_si128(x, sizeof(byte)); - v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - - return Sse2.unpacklo_epi8(zw, y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 0, 2)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 1, 2)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzz = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 2)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - - return Sse2.unpacklo_epi8(zw, zw); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwx(v128 x) - { - if (Sse2.IsSse2Supported) - { - return Sse2.shufflelo_epi16(x, Sse.SHUFFLE(3, 3, 0, 1)); - } - else if (Sse2.IsSse2Supported) - { - v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - - return Sse2.unpacklo_epi16(zw, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 y = Sse2.bsrli_si128(x, sizeof(byte)); - v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - - return Sse2.unpacklo_epi16(zw, y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zwz(v128 x) - { - if (Sse2.IsSse2Supported) - { - return Sse2.shufflelo_epi16(x, Sse.SHUFFLE(3, 3, 1, 1)); - } - else if (Sse2.IsSse2Supported) - { - v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - - return Sse2.unpacklo_epi16(zw, zw); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 zzww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 2)); - - return Sse2.bsrli_si128(zzww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwxx = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 0, 3)); - - return Sse2.bsrli_si128(wwxx, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - int wxyz = math.rol(Sse2.cvtsi128_si32(x), 8); - - return Sse2.cvtsi32_si128(wxyz); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 0, 3)); - - return Sse2.packus_epi16(w_x_z, w_x_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wxw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 w = Sse2.bsrli_si128(x, 3 * sizeof(byte)); - v128 wx = Sse2.unpacklo_epi8(w, x); - - return Sse2.unpacklo_epi16(wx, wx); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 1, 3)); - - return Sse2.packus_epi16(w_y_x, w_y_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 1, 3)); - - return Sse2.bsrli_si128(wwyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 1, 3)); - - return Sse2.packus_epi16(w_y_z, w_y_z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wyw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 1, 3)); - - return Sse2.packus_epi16(w_y_w, w_y_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 2, 3)); - - return Sse2.packus_epi16(w_z_x, w_z_x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 2, 3)); - - return Sse2.packus_epi16(w_z_y, w_z_y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwzz = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 2, 3)); - - return Sse2.bsrli_si128(wwzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wzw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); - v128 w_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 2, 3)); - - return Sse2.packus_epi16(w_z_w, w_z_w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 0, 3)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 1, 3)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wwz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 2, 3)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 www(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - - return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(3, 3, 3, 3)); - } - else throw new IllegalInstructionException(); - } - - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xx(v128 x) - { if (Sse2.IsSse2Supported) - { - return Sse2.unpacklo_epi8(x, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xy(v128 x) - { if (Sse2.IsSse2Supported) - { - return (v128)x; - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - - return Sse2.unpacklo_epi8(x, z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 xw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 w = Sse2.bsrli_si128(x, 3 * sizeof(byte)); - - return Sse2.unpacklo_epi8(x, w); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 y = Sse2.bsrli_si128(x, sizeof(byte)); - - return Sse2.unpacklo_epi8(y, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 y = Sse2.bsrli_si128(x, sizeof(byte)); - - return Sse2.unpacklo_epi8(y, y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yz(v128 x) - { if (Sse2.IsSse2Supported) - { - return Sse2.bsrli_si128(x, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 yw(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(1, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 yyww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 1)); - - return Sse2.bsrli_si128(yyww, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zx(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - - return Sse2.unpacklo_epi8(z, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zy(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 y = Sse2.bsrli_si128(x, sizeof(byte)); - v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - - return Sse2.unpacklo_epi8(z, y); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zz(v128 x) - { if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(2, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); - - return Sse2.unpacklo_epi8(z, z); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 zw(v128 x) - { - if (Sse2.IsSse2Supported) - { - return Sse2.bsrli_si128(x, 2 * sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wx(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 w = Sse2.bsrli_si128(x, 3 * sizeof(byte)); - - return Sse2.unpacklo_epi8(w, x); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wy(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 1, 3)); - - return Sse2.bsrli_si128(wwyy, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 wz(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - v128 wwzz = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 2, 3)); - - return Sse2.bsrli_si128(wwzz, sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static v128 ww(v128 x) - { - if (Ssse3.IsSsse3Supported) - { - return Ssse3.shuffle_epi8(x, new v128(3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - } - else if (Sse2.IsSse2Supported) - { - v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); - - return Sse2.bsrli_si128(xxyyzzww, 6 * sizeof(byte)); - } - else throw new IllegalInstructionException(); - } - } - } - } -} +using System.Runtime.CompilerServices; +using Unity.Mathematics; +using Unity.Burst.Intrinsics; + +using static Unity.Burst.Intrinsics.X86; + +namespace MaxMath +{ + unsafe internal static partial class Shuffle + { + internal static partial class Bytes + { + internal static partial class Get + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, Sse2.setzero_si128()); + } + else if (Sse2.IsSse2Supported) + { + v128 _xxyy = Sse2.unpacklo_epi8(x, x); + + return Sse2.unpacklo_epi16(_xxyy, _xxyy); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyy = Sse2.unpacklo_epi8(x, x); + + return Sse2.unpacklo_epi16(xxyy, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 xxxxzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 2, 0, 0)); + + return Sse2.bsrli_si128(xxxxzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 xxxxww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 0, 0)); + + return Sse2.bsrli_si128(xxxxww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xx = Sse2.unpacklo_epi8(x, x); + + return Sse2.unpacklo_epi8(x, xx); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxyy(v128 x) + { + if (Sse2.IsSse2Supported) + { + return Sse2.unpacklo_epi8(x, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_x_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 1, 0, 0)); + + return Sse2.packus_epi16(x_x_y_z, x_x_y_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_x_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 0, 0)); + + return Sse2.packus_epi16(x_x_y_w, x_x_y_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_x_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 0, 0)); + + return Sse2.packus_epi16(x_x_z_x, x_x_z_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + v128 xz = Sse2.unpacklo_epi8(x, z); + + return Sse2.unpacklo_epi8(xz, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 0)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_x_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 0, 0)); + + return Sse2.packus_epi16(x_x_z_w, x_x_z_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxwx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_x_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 0, 0)); + + return Sse2.packus_epi16(x_x_w_x, x_x_w_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxwy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_x_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 0, 0)); + + return Sse2.packus_epi16(x_x_w_y, x_x_w_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxwz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_x_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 0, 0)); + + return Sse2.packus_epi16(x_x_w_z, x_x_w_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 0)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xyxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 _xxyy = Sse2.unpacklo_epi8(x, x); + + return Sse2.unpacklo_epi16(x, _xxyy); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xyxy(v128 x) + { + if (Sse2.IsSse2Supported) + { + return Sse2.shufflelo_epi16(x, Sse.SHUFFLE(0, 0, 0, 0)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xyxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + v128 xz = Sse2.unpacklo_epi8(x, z); + + return Sse2.unpacklo_epi16(x, xz); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xyxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_y_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 1, 0)); + + return Sse2.packus_epi16(x_y_x_w, x_y_x_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xyyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 y = Sse2.bsrli_si128(x, sizeof(byte)); + v128 yx = Sse2.unpacklo_epi8(y, x); + + return Sse2.unpacklo_epi16(x, yx); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xyyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 xxyyyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 1, 1, 0)); + + return Sse2.bsrli_si128(xxyyyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xyyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); + + return Sse2.unpacklo_epi8(x, yz); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xyyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 xxyyww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 1, 0)); + + return Sse2.bsrli_si128(xxyyww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xyzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 _xyz = Sse2.bslli_si128(x, sizeof(byte)); + v128 _xyzx = Sse2.unpacklo_epi32(_xyz, x); + + return Sse2.bsrli_si128(_xyzx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xyzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_y_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 2, 1, 0)); + + return Sse2.packus_epi16(x_y_z_y, x_y_z_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xyzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + v128 zz = Sse2.unpacklo_epi8(z, z); + + return Sse2.unpacklo_epi16(x, zz); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xywx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_y_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 1, 0)); + + return Sse2.packus_epi16(x_y_w_x, x_y_w_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xywy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_y_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 1, 0)); + + return Sse2.packus_epi16(x_y_w_y, x_y_w_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xywz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 1, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_y_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 1, 0)); + + return Sse2.packus_epi16(x_y_w_z, x_y_w_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xyww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_y_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 1, 0)); + + return Sse2.packus_epi16(x_y_w_w, x_y_w_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_z_x_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 2, 0)); + + return Sse2.packus_epi16(x_z_x_x, x_z_x_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + v128 xz = Sse2.unpacklo_epi8(x, z); + + return Sse2.unpacklo_epi16(xz, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + v128 xz = Sse2.unpacklo_epi8(x, z); + + return Sse2.unpacklo_epi16(xz, xz); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_z_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 2, 0)); + + return Sse2.packus_epi16(x_z_x_w, x_z_x_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + v128 zx = Sse2.unpacklo_epi8(z, x); + + return Sse2.unpacklo_epi8(x, zx); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_z_y_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 1, 2, 0)); + + return Sse2.packus_epi16(x_z_y_y, x_z_y_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + v128 zz = Sse2.unpacklo_epi8(z, z); + + return Sse2.unpacklo_epi8(x, zz); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + + return Sse2.unpacklo_epi8(x, zw); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 xxzzxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 0)); + + return Sse2.bsrli_si128(xxzzxx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 xxzzyy = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 1, 2, 0)); + + return Sse2.bsrli_si128(xxzzyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 xxzzzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 2, 2, 0)); + + return Sse2.bsrli_si128(xxzzzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 xxzzww = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 3, 2, 0)); + + return Sse2.bsrli_si128(xxzzww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzwx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_z_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 2, 0)); + + return Sse2.packus_epi16(x_z_w_x, x_z_w_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzwy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_z_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 2, 0)); + + return Sse2.packus_epi16(x_z_w_y, x_z_w_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzwz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_z_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 2, 0)); + + return Sse2.packus_epi16(x_z_w_z, x_z_w_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_z_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 2, 0)); + + return Sse2.packus_epi16(x_z_w_w, x_z_w_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_w_x_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 3, 0)); + + return Sse2.packus_epi16(x_w_x_x, x_w_x_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_w_x_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 0, 3, 0)); + + return Sse2.packus_epi16(x_w_x_y, x_w_x_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_w_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 3, 0)); + + return Sse2.packus_epi16(x_w_x_z, x_w_x_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_w_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 3, 0)); + + return Sse2.packus_epi16(x_w_x_w, x_w_x_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_w_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 3, 0)); + + return Sse2.packus_epi16(x_w_y_x, x_w_y_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_w_y_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 1, 3, 0)); + + return Sse2.packus_epi16(x_w_y_y, x_w_y_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_w_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 1, 3, 0)); + + return Sse2.packus_epi16(x_w_y_z, x_w_y_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_w_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 3, 0)); + + return Sse2.packus_epi16(x_w_y_w, x_w_y_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_w_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 3, 0)); + + return Sse2.packus_epi16(x_w_z_x, x_w_z_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_w_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 2, 3, 0)); + + return Sse2.packus_epi16(x_w_z_y, x_w_z_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_w_z_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 2, 3, 0)); + + return Sse2.packus_epi16(x_w_z_z, x_w_z_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_w_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 3, 0)); + + return Sse2.packus_epi16(x_w_z_w, x_w_z_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwwx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 xxwwxx = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 0)); + + return Sse2.bsrli_si128(xxwwxx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwwy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 xxwwyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 1, 3, 0)); + + return Sse2.bsrli_si128(xxwwyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwwz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 xxwwzz = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 2, 3, 0)); + + return Sse2.bsrli_si128(xxwwzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 xxwwww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 3, 0)); + + return Sse2.bsrli_si128(xxwwww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 yyxxxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 0, 1)); + + return Sse2.bsrli_si128(yyxxxx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 y = Sse2.bsrli_si128(x, sizeof(byte)); + v128 yx = Sse2.unpacklo_epi8(y, x); + + return Sse2.unpacklo_epi16(yx, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 yyxxzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 2, 0, 1)); + + return Sse2.bsrli_si128(yyxxzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 yyxxww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 0, 1)); + + return Sse2.bsrli_si128(yyxxww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 y = Sse2.bsrli_si128(x, sizeof(byte)); + v128 yx = Sse2.unpacklo_epi8(y, x); + + return Sse2.unpacklo_epi16(yx, yx); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 y = Sse2.bsrli_si128(x, sizeof(byte)); + v128 yy = Sse2.unpacklo_epi8(y, y); + + return Sse2.unpacklo_epi8(yy, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); + v128 yx = Sse2.unpacklo_epi8(yz, x); + + return Sse2.unpacklo_epi16(yx, yz); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_x_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 0, 1)); + + return Sse2.packus_epi16(y_x_y_w, y_x_y_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); + v128 xx = Sse2.unpacklo_epi8(x, x); + + return Sse2.unpacklo_epi8(yz, xx); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); + + return Sse2.unpacklo_epi8(yz, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_x_z_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 2, 0, 1)); + + return Sse2.packus_epi16(y_x_z_z, y_x_z_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_x_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 0, 1)); + + return Sse2.packus_epi16(y_x_z_w, y_x_z_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxwx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_x_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 0, 1)); + + return Sse2.packus_epi16(y_x_w_x, y_x_w_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxwy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_x_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 0, 1)); + + return Sse2.packus_epi16(y_x_w_y, y_x_w_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxwz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_x_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 0, 1)); + + return Sse2.packus_epi16(y_x_w_z, y_x_w_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_x_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 0, 1)); + + return Sse2.packus_epi16(y_x_w_w, y_x_w_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyy = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyy, Sse.SHUFFLE(0, 1, 0, 1)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 y = Sse2.bsrli_si128(x, sizeof(byte)); + v128 yy = Sse2.unpacklo_epi8(y, y); + + return Sse2.unpacklo_epi16(yy, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); + v128 yx = Sse2.unpacklo_epi8(yz, x); + + return Sse2.unpacklo_epi8(yx, yz); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_y_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 1, 1)); + + return Sse2.packus_epi16(y_y_x_w, y_y_x_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 yyyyxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 1, 1)); + + return Sse2.bsrli_si128(yyyyxx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(1, 1, 1, 1)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 yyyyzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 2, 1, 1)); + + return Sse2.bsrli_si128(yyyyzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 yyyyww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 1, 1)); + + return Sse2.bsrli_si128(yyyyww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_y_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 1, 1)); + + return Sse2.packus_epi16(y_y_z_x, y_y_z_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); + v128 yy = Sse2.unpacklo_epi8(yz, yz); + + return Sse2.unpacklo_epi8(yz, yy); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 1)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_y_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 1, 1)); + + return Sse2.packus_epi16(y_y_z_w, y_y_z_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yywx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_y_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 1, 1)); + + return Sse2.packus_epi16(y_y_w_x, y_y_w_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yywy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_y_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 1, 1)); + + return Sse2.packus_epi16(y_y_w_y, y_y_w_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yywz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_y_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 1, 1)); + + return Sse2.packus_epi16(y_y_w_z, y_y_w_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 3, 1)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); + v128 xx = Sse2.unpacklo_epi8(x, x); + + return Sse2.unpacklo_epi16(yz, xx); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); + + return Sse2.unpacklo_epi16(yz, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_z_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 2, 1)); + + return Sse2.packus_epi16(y_z_x_z, y_z_x_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_z_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 2, 1)); + + return Sse2.packus_epi16(y_z_x_w, y_z_x_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); + v128 yx = Sse2.unpacklo_epi8(yz, x); + + return Sse2.unpacklo_epi16(yz, yx); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); + v128 yy = Sse2.unpacklo_epi8(yz, yz); + + return Sse2.unpacklo_epi16(yz, yy); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); + + return Sse2.unpacklo_epi16(yz, yz); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_z_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 2, 1)); + + return Sse2.packus_epi16(y_z_y_w, y_z_y_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 yyzzxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 1)); + + return Sse2.bsrli_si128(yyzzxx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 yyzzyy = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 1, 2, 1)); + + return Sse2.bsrli_si128(yyzzyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 yyzzzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 2, 2, 1)); + + return Sse2.bsrli_si128(yyzzzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_z_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 2, 1)); + + return Sse2.packus_epi16(y_z_z_w, y_z_z_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzwx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + int yzwx = math.ror(Sse2.cvtsi128_si32(x), 8); + + return Sse2.cvtsi32_si128(yzwx); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzwy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_z_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 2, 1)); + + return Sse2.packus_epi16(y_z_w_y, y_z_w_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzwz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_z_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 2, 1)); + + return Sse2.packus_epi16(y_z_w_z, y_z_w_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_z_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 2, 1)); + + return Sse2.packus_epi16(y_z_w_w, y_z_w_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_w_x_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 3, 1)); + + return Sse2.packus_epi16(y_w_x_x, y_w_x_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_w_x_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 0, 3, 1)); + + return Sse2.packus_epi16(y_w_x_y, y_w_x_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_w_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 3, 1)); + + return Sse2.packus_epi16(y_w_x_z, y_w_x_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_w_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 3, 1)); + + return Sse2.packus_epi16(y_w_x_w, y_w_x_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_w_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 3, 1)); + + return Sse2.packus_epi16(y_w_y_x, y_w_y_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_w_y_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 1, 3, 1)); + + return Sse2.packus_epi16(y_w_y_y, y_w_y_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_w_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 1, 3, 1)); + + return Sse2.packus_epi16(y_w_y_z, y_w_y_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_w_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 3, 1)); + + return Sse2.packus_epi16(y_w_y_w, y_w_y_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_w_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 3, 1)); + + return Sse2.packus_epi16(y_w_z_x, y_w_z_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_w_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 2, 3, 1)); + + return Sse2.packus_epi16(y_w_z_y, y_w_z_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_w_z_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 2, 3, 1)); + + return Sse2.packus_epi16(y_w_z_z, y_w_z_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_w_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 3, 1)); + + return Sse2.packus_epi16(y_w_z_w, y_w_z_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywwx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 yywwxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 3, 1)); + + return Sse2.bsrli_si128(yywwxx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywwy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 yywwyy = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 1, 3, 1)); + + return Sse2.bsrli_si128(yywwyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywwz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 yywwzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 2, 3, 1)); + + return Sse2.bsrli_si128(yywwzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 yywwww = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 3, 3, 1)); + + return Sse2.bsrli_si128(yywwww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 zzxxxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 0, 2)); + + return Sse2.bsrli_si128(zzxxxx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 zzxxyy = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 1, 0, 2)); + + return Sse2.bsrli_si128(zzxxyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 zzxxzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 2, 0, 2)); + + return Sse2.bsrli_si128(zzxxzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 zzxxww = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 3, 0, 2)); + + return Sse2.bsrli_si128(zzxxww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_x_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 0, 2)); + + return Sse2.packus_epi16(z_x_y_x, z_x_y_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_x_y_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 1, 0, 2)); + + return Sse2.packus_epi16(z_x_y_y, z_x_y_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_x_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 1, 0, 2)); + + return Sse2.packus_epi16(z_x_y_z, z_x_y_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_x_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 0, 2)); + + return Sse2.packus_epi16(z_x_y_w, z_x_y_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_x_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 0, 2)); + + return Sse2.packus_epi16(z_x_z_x, z_x_z_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + v128 zz = Sse2.unpacklo_epi8(z, z); + + return Sse2.unpacklo_epi8(zz, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_x_z_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 2, 0, 2)); + + return Sse2.packus_epi16(z_x_z_z, z_x_z_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_x_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 0, 2)); + + return Sse2.packus_epi16(z_x_z_w, z_x_z_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxwx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_x_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 0, 2)); + + return Sse2.packus_epi16(z_x_w_x, z_x_w_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxwy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_x_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 0, 2)); + + return Sse2.packus_epi16(z_x_w_y, z_x_w_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxwz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_x_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 0, 2)); + + return Sse2.packus_epi16(z_x_w_z, z_x_w_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_x_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 0, 2)); + + return Sse2.packus_epi16(z_x_w_w, z_x_w_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_y_x_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 1, 2)); + + return Sse2.packus_epi16(z_y_x_x, z_y_x_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_y_x_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 0, 1, 2)); + + return Sse2.packus_epi16(z_y_x_y, z_y_x_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_y_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 1, 2)); + + return Sse2.packus_epi16(z_y_x_z, z_y_x_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_y_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 1, 2)); + + return Sse2.packus_epi16(z_y_x_w, z_y_x_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 zzyyxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 1, 2)); + + return Sse2.bsrli_si128(zzyyxx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 zzyyyy = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 1, 1, 2)); + + return Sse2.bsrli_si128(zzyyyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 zzyyzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 2, 1, 2)); + + return Sse2.bsrli_si128(zzyyzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 zzyyww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 1, 2)); + + return Sse2.bsrli_si128(zzyyww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_y_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 1, 2)); + + return Sse2.packus_epi16(z_y_z_x, z_y_z_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_y_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 2, 1, 2)); + + return Sse2.packus_epi16(z_y_z_y, z_y_z_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_y_z_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 2, 1, 2)); + + return Sse2.packus_epi16(z_y_z_z, z_y_z_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_y_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 1, 2)); + + return Sse2.packus_epi16(z_y_z_w, z_y_z_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zywx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_y_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 1, 2)); + + return Sse2.packus_epi16(z_y_w_x, z_y_w_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zywy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_y_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 1, 2)); + + return Sse2.packus_epi16(z_y_w_y, z_y_w_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zywz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_y_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 1, 2)); + + return Sse2.packus_epi16(z_y_w_z, z_y_w_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_y_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 1, 2)); + + return Sse2.packus_epi16(z_y_w_w, z_y_w_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 0, 2)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + v128 zz = Sse2.unpacklo_epi8(z, z); + + return Sse2.unpacklo_epi16(zz, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_z_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 2, 2)); + + return Sse2.packus_epi16(z_z_x_z, z_z_x_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_z_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 2, 2)); + + return Sse2.packus_epi16(z_z_x_w, z_z_x_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_z_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 2, 2)); + + return Sse2.packus_epi16(z_z_y_x, z_z_y_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 1, 2)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_z_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 1, 2, 2)); + + return Sse2.packus_epi16(z_z_y_z, z_z_y_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_z_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 2, 2)); + + return Sse2.packus_epi16(z_z_y_w, z_z_y_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 zzzzxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 2)); + + return Sse2.bsrli_si128(zzzzxx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 zzzzyy = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 1, 2, 2)); + + return Sse2.bsrli_si128(zzzzyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 2)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 zzzzww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 2, 2)); + + return Sse2.bsrli_si128(zzzzww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzwx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_z_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 2, 2)); + + return Sse2.packus_epi16(z_z_w_x, z_z_w_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzwy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_z_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 2, 2)); + + return Sse2.packus_epi16(z_z_w_y, z_z_w_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzwz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_z_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 2, 2)); + + return Sse2.packus_epi16(z_z_w_z, z_z_w_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 2)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_w_x_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 3, 2)); + + return Sse2.packus_epi16(z_w_x_x, z_w_x_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwxy(v128 x) + { + if (Sse2.IsSse2Supported) + { + return Sse2.shufflelo_epi16(x, Sse.SHUFFLE(3, 3, 0, 1)); + } + else if (Sse2.IsSse2Supported) + { + v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + + return Sse2.unpacklo_epi16(zw, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_w_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 3, 2)); + + return Sse2.packus_epi16(z_w_x_z, z_w_x_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_w_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 3, 2)); + + return Sse2.packus_epi16(z_w_x_w, z_w_x_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_w_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 3, 2)); + + return Sse2.packus_epi16(z_w_y_x, z_w_y_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_w_y_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 1, 3, 2)); + + return Sse2.packus_epi16(z_w_y_y, z_w_y_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_w_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 1, 3, 2)); + + return Sse2.packus_epi16(z_w_y_z, z_w_y_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_w_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 3, 2)); + + return Sse2.packus_epi16(z_w_y_w, z_w_y_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_w_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 3, 2)); + + return Sse2.packus_epi16(z_w_z_x, z_w_z_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_w_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 2, 3, 2)); + + return Sse2.packus_epi16(z_w_z_y, z_w_z_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_w_z_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 2, 3, 2)); + + return Sse2.packus_epi16(z_w_z_z, z_w_z_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwzw(v128 x) + { + if (Sse2.IsSse2Supported) + { + return Sse2.shufflelo_epi16(x, Sse.SHUFFLE(3, 3, 1, 1)); + } + else if (Sse2.IsSse2Supported) + { + v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + + return Sse2.unpacklo_epi16(zw, zw); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwwx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 zzwwxx = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 2)); + + return Sse2.bsrli_si128(zzwwxx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwwy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 zzwwyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 1, 3, 2)); + + return Sse2.bsrli_si128(zzwwyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwwz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 zzwwzz = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 2, 3, 2)); + + return Sse2.bsrli_si128(zzwwzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 zzwwww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 3, 2)); + + return Sse2.bsrli_si128(zzwwww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwxxxx = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 0, 3)); + + return Sse2.bsrli_si128(wwxxxx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwxxyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 1, 0, 3)); + + return Sse2.bsrli_si128(wwxxyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwxxzz = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 2, 0, 3)); + + return Sse2.bsrli_si128(wwxxzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwxxww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 0, 3)); + + return Sse2.bsrli_si128(wwxxww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_x_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 0, 3)); + + return Sse2.packus_epi16(w_x_y_x, w_x_y_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_x_y_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 1, 0, 3)); + + return Sse2.packus_epi16(w_x_y_y, w_x_y_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + int wxyz = math.rol(Sse2.cvtsi128_si32(x), 8); + + return Sse2.cvtsi32_si128(wxyz); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_x_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 0, 3)); + + return Sse2.packus_epi16(w_x_y_w, w_x_y_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_x_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 0, 3)); + + return Sse2.packus_epi16(w_x_z_x, w_x_z_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_x_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 2, 0, 3)); + + return Sse2.packus_epi16(w_x_z_y, w_x_z_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_x_z_t = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 2, 0, 3)); + + return Sse2.packus_epi16(w_x_z_t, w_x_z_t); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_x_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 0, 3)); + + return Sse2.packus_epi16(w_x_z_w, w_x_z_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxwx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_x_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 0, 3)); + + return Sse2.packus_epi16(w_x_w_x, w_x_w_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxwy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_x_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 0, 3)); + + return Sse2.packus_epi16(w_x_w_y, w_x_w_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxwz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_x_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 0, 3)); + + return Sse2.packus_epi16(w_x_w_z, w_x_w_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_x_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 0, 3)); + + return Sse2.packus_epi16(w_x_w_w, w_x_w_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_y_x_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 1, 3)); + + return Sse2.packus_epi16(w_y_x_x, w_y_x_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_y_x_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 0, 1, 3)); + + return Sse2.packus_epi16(w_y_x_y, w_y_x_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_y_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 1, 3)); + + return Sse2.packus_epi16(w_y_x_z, w_y_x_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_y_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 1, 3)); + + return Sse2.packus_epi16(w_y_x_w, w_y_x_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwyyxx = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 1, 3)); + + return Sse2.bsrli_si128(wwyyxx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwyyyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 1, 1, 3)); + + return Sse2.bsrli_si128(wwyyyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwyyzz = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 2, 1, 3)); + + return Sse2.bsrli_si128(wwyyzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 wwyyww = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 3, 1, 3)); + + return Sse2.bsrli_si128(wwyyww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_y_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 1, 3)); + + return Sse2.packus_epi16(w_y_z_x, w_y_z_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_y_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 2, 1, 3)); + + return Sse2.packus_epi16(w_y_z_y, w_y_z_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_y_z_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 2, 1, 3)); + + return Sse2.packus_epi16(w_y_z_z, w_y_z_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_y_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 1, 3)); + + return Sse2.packus_epi16(w_y_z_w, w_y_z_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wywx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_y_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 1, 3)); + + return Sse2.packus_epi16(w_y_w_x, w_y_w_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wywy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_y_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 1, 3)); + + return Sse2.packus_epi16(w_y_w_y, w_y_w_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wywz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_y_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 1, 3)); + + return Sse2.packus_epi16(w_y_w_z, w_y_w_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_y_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 1, 3)); + + return Sse2.packus_epi16(w_y_w_w, w_y_w_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_z_x_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 2, 3)); + + return Sse2.packus_epi16(w_z_x_x, w_z_x_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_z_x_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 0, 2, 3)); + + return Sse2.packus_epi16(w_z_x_y, w_z_x_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_z_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 2, 3)); + + return Sse2.packus_epi16(w_z_x_z, w_z_x_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_z_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 2, 3)); + + return Sse2.packus_epi16(w_z_x_w, w_z_x_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + int wzyx = maxmath.reversebytes(Sse2.cvtsi128_si32(x)); + + return Sse2.cvtsi32_si128(wzyx); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_z_y_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 1, 2, 3)); + + return Sse2.packus_epi16(w_z_y_y, w_z_y_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_z_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 1, 2, 3)); + + return Sse2.packus_epi16(w_z_y_z, w_z_y_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_z_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 2, 3)); + + return Sse2.packus_epi16(w_z_y_w, w_z_y_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwzzxx = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 2, 3)); + + return Sse2.bsrli_si128(wwzzxx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwzzyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 1, 2, 3)); + + return Sse2.bsrli_si128(wwzzyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwzzzz = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 2, 2, 3)); + + return Sse2.bsrli_si128(wwzzzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwzzww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 3, 2, 3)); + + return Sse2.bsrli_si128(wwzzww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzwx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_z_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 2, 3)); + + return Sse2.packus_epi16(w_z_w_x, w_z_w_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzwy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_z_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 3, 2, 3)); + + return Sse2.packus_epi16(w_z_w_y, w_z_w_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzwz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_z_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 3, 2, 3)); + + return Sse2.packus_epi16(w_z_w_z, w_z_w_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_z_w_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 3, 2, 3)); + + return Sse2.packus_epi16(w_z_w_w, w_z_w_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 0, 3)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 ww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 0, 3)); + + return Sse2.unpacklo_epi16(ww, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_w_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 0, 3, 3)); + + return Sse2.packus_epi16(w_w_x_z, w_w_x_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_w_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 0, 3, 3)); + + return Sse2.packus_epi16(w_w_x_w, w_w_x_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_w_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 3, 3)); + + return Sse2.packus_epi16(w_w_y_x, w_w_y_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 1, 3)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_w_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(2, 1, 3, 3)); + + return Sse2.packus_epi16(w_w_y_z, w_w_y_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_w_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 1, 3, 3)); + + return Sse2.packus_epi16(w_w_y_w, w_w_y_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_w_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 3, 3)); + + return Sse2.packus_epi16(w_w_z_x, w_w_z_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_w_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(1, 2, 3, 3)); + + return Sse2.packus_epi16(w_w_z_y, w_w_z_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 2, 3)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_w_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(3, 2, 3, 3)); + + return Sse2.packus_epi16(w_w_z_w, w_w_z_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwwx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwwwxx = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 3)); + + return Sse2.bsrli_si128(wwwwxx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwwy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwwwyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 1, 3, 3)); + + return Sse2.bsrli_si128(wwwwyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwwz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwwwzz = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 2, 3, 3)); + + return Sse2.bsrli_si128(wwwwzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 3)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, Sse2.setzero_si128()); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyy = Sse2.unpacklo_epi8(x, x); + + return Sse2.unpacklo_epi16(xxyy, xxyy); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxy(v128 x) + { + if (Sse2.IsSse2Supported) + { + return Sse2.unpacklo_epi8(x, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 0)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 0)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xyx(v128 x) + { + if (Sse2.IsSse2Supported) + { + return Sse2.shufflelo_epi16(x, Sse.SHUFFLE(0, 0, 0, 0)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyy = Sse2.unpacklo_epi8(x, x); + + return Sse2.bsrli_si128(xxyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xyz(v128 x) + { + if (Sse2.IsSse2Supported) + { + return (v128)x; + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 w = Sse2.bsrli_si128(x, 3 * sizeof(byte)); + + return Sse2.unpacklo_epi16(x, w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + v128 xz = Sse2.unpacklo_epi8(x, z); + + return Sse2.unpacklo_epi16(xz, xz); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 2, 0)); + + return Sse2.packus_epi16(x_z_y, x_z_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 xxzz = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 0)); + + return Sse2.bsrli_si128(xxzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 2, 0)); + + return Sse2.packus_epi16(x_z_w, x_z_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 w = Sse2.bsrli_si128(x, 3 * sizeof(byte)); + v128 xx = Sse2.unpacklo_epi8(x, x); + + return Sse2.unpacklo_epi8(xx, w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 w = Sse2.bsrli_si128(x, 3 * sizeof(byte)); + + return Sse2.unpacklo_epi8(x, w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xwz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 x_w_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 3, 0)); + + return Sse2.packus_epi16(x_w_z, x_w_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 xxww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 0)); + + return Sse2.bsrli_si128(xxww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 y = Sse2.bsrli_si128(x, sizeof(byte)); + v128 yx = Sse2.unpacklo_epi8(y, x); + + return Sse2.unpacklo_epi16(yx, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xyxy = Sse2.shufflelo_epi16(x, Sse.SHUFFLE(0, 0, 0, 0)); + + return Sse2.bsrli_si128(xyxy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 0, 1)); + + return Sse2.packus_epi16(y_x_z, y_x_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_x_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 0, 1)); + + return Sse2.packus_epi16(y_x_w, y_x_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyy = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyy, Sse.SHUFFLE(0, 0, 0, 1)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyy = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyy, Sse.SHUFFLE(1, 1, 1, 1)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 2, 1)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 1)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); + + return Sse2.unpacklo_epi16(yz, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); + + return Sse2.unpacklo_epi16(yz, yz); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + + return Sse2.bsrli_si128(xxyyzz, 3 * sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yzw(v128 x) + { + if (Sse2.IsSse2Supported) + { + return Sse2.bsrli_si128(x, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_w_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 3, 1)); + + return Sse2.packus_epi16(y_w_x, y_w_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 y_w_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 3, 1)); + + return Sse2.packus_epi16(y_w_y, y_w_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ywz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 yz = Sse2.bsrli_si128(x, sizeof(byte)); + v128 w = Sse2.bsrli_si128(x, 3 * sizeof(byte)); + + return Sse2.unpacklo_epi8(yz, w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 yyww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 1)); + + return Sse2.bsrli_si128(yyww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 zzxx = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 0, 2)); + + return Sse2.bsrli_si128(zzxx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_x_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 0, 2)); + + return Sse2.packus_epi16(z_x_y, z_x_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 0, 2)); + + return Sse2.packus_epi16(z_x_z, z_x_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + + return Sse2.unpacklo_epi8(zw, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 1, 2)); + + return Sse2.packus_epi16(z_y_x, z_y_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + v128 zzyy = Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 1, 2)); + + return Sse2.bsrli_si128(zzyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 z_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 1, 2)); + + return Sse2.packus_epi16(z_y_z, z_y_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 y = Sse2.bsrli_si128(x, sizeof(byte)); + v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + + return Sse2.unpacklo_epi8(zw, y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 0, 2)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 1, 2)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzz = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzz, Sse.SHUFFLE(0, 0, 2, 2)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + + return Sse2.unpacklo_epi8(zw, zw); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwx(v128 x) + { + if (Sse2.IsSse2Supported) + { + return Sse2.shufflelo_epi16(x, Sse.SHUFFLE(3, 3, 0, 1)); + } + else if (Sse2.IsSse2Supported) + { + v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + + return Sse2.unpacklo_epi16(zw, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 y = Sse2.bsrli_si128(x, sizeof(byte)); + v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + + return Sse2.unpacklo_epi16(zw, y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zwz(v128 x) + { + if (Sse2.IsSse2Supported) + { + return Sse2.shufflelo_epi16(x, Sse.SHUFFLE(3, 3, 1, 1)); + } + else if (Sse2.IsSse2Supported) + { + v128 zw = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + + return Sse2.unpacklo_epi16(zw, zw); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 zzww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 2)); + + return Sse2.bsrli_si128(zzww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwxx = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 0, 3)); + + return Sse2.bsrli_si128(wwxx, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + int wxyz = math.rol(Sse2.cvtsi128_si32(x), 8); + + return Sse2.cvtsi32_si128(wxyz); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_x_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 0, 3)); + + return Sse2.packus_epi16(w_x_z, w_x_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wxw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 w = Sse2.bsrli_si128(x, 3 * sizeof(byte)); + v128 wx = Sse2.unpacklo_epi8(w, x); + + return Sse2.unpacklo_epi16(wx, wx); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_y_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 1, 3)); + + return Sse2.packus_epi16(w_y_x, w_y_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 1, 3)); + + return Sse2.bsrli_si128(wwyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_y_z = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 2, 1, 3)); + + return Sse2.packus_epi16(w_y_z, w_y_z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wyw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_y_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 1, 3)); + + return Sse2.packus_epi16(w_y_w, w_y_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_z_x = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 0, 2, 3)); + + return Sse2.packus_epi16(w_z_x, w_z_x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_z_y = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 1, 2, 3)); + + return Sse2.packus_epi16(w_z_y, w_z_y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwzz = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 2, 3)); + + return Sse2.bsrli_si128(wwzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wzw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 cast = Sse2.unpacklo_epi8(x, Sse2.setzero_si128()); + v128 w_z_w = Sse2.shufflelo_epi16(cast, Sse.SHUFFLE(0, 3, 2, 3)); + + return Sse2.packus_epi16(w_z_w, w_z_w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 0, 3)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 1, 3)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wwz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 2, 3)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 www(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + + return Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(3, 3, 3, 3)); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xx(v128 x) + { + if (Sse2.IsSse2Supported) + { + return Sse2.unpacklo_epi8(x, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xy(v128 x) + { + if (Sse2.IsSse2Supported) + { + return (v128)x; + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + + return Sse2.unpacklo_epi8(x, z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 xw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 w = Sse2.bsrli_si128(x, 3 * sizeof(byte)); + + return Sse2.unpacklo_epi8(x, w); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 y = Sse2.bsrli_si128(x, sizeof(byte)); + + return Sse2.unpacklo_epi8(y, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 y = Sse2.bsrli_si128(x, sizeof(byte)); + + return Sse2.unpacklo_epi8(y, y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yz(v128 x) + { + if (Sse2.IsSse2Supported) + { + return Sse2.bsrli_si128(x, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 yw(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(1, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 yyww = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 3, 1)); + + return Sse2.bsrli_si128(yyww, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + + return Sse2.unpacklo_epi8(z, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 y = Sse2.bsrli_si128(x, sizeof(byte)); + v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + + return Sse2.unpacklo_epi8(z, y); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(2, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 z = Sse2.bsrli_si128(x, 2 * sizeof(byte)); + + return Sse2.unpacklo_epi8(z, z); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 zw(v128 x) + { + if (Sse2.IsSse2Supported) + { + return Sse2.bsrli_si128(x, 2 * sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wx(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 w = Sse2.bsrli_si128(x, 3 * sizeof(byte)); + + return Sse2.unpacklo_epi8(w, x); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wy(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwyy = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 1, 3)); + + return Sse2.bsrli_si128(wwyy, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 wz(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + v128 wwzz = Sse2.shufflelo_epi16(xxyyzzww, Sse.SHUFFLE(0, 0, 2, 3)); + + return Sse2.bsrli_si128(wwzz, sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static v128 ww(v128 x) + { + if (Ssse3.IsSsse3Supported) + { + return Ssse3.shuffle_epi8(x, new v128(3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + } + else if (Sse2.IsSse2Supported) + { + v128 xxyyzzww = Sse2.unpacklo_epi8(x, x); + + return Sse2.bsrli_si128(xxyyzzww, 6 * sizeof(byte)); + } + else throw new IllegalInstructionException(); + } + } + } + } +} diff --git a/Runtime/__Internal/TODO/Hypot.cs b/Runtime/__Internal/TODO/Hypot.cs index f8c0a65..1e72391 100644 --- a/Runtime/__Internal/TODO/Hypot.cs +++ b/Runtime/__Internal/TODO/Hypot.cs @@ -1,42 +1,42 @@ - //public static v128 hypot_ps(v128 a, v128 b) - //{ - // if (Constant.IsConstantExpression(a)) - // { - // return Sse.sqrt_ps(fmadd_ps(b, b, Sse.mul_ps(a, a))); - // } - // else if (Constant.IsConstantExpression(b)) - // { - // return Sse.sqrt_ps(fmadd_ps(a, a, Sse.mul_ps(b, b))); - // } - // else - // { - // return Sse.sqrt_ps(Sse.add_ps(Sse.mul_ps(a, a), Sse.mul_ps(b, b))); - // } - //} - // - // - // - // - // - //public static v128 hypot_epi16(v128 a, v128 b, byte elements = 8) - //{ - // if (elements <= 4) - // { - // v128 interleaved = Sse2.unpacklo_epi16(a, b); - // v128 radicands32 = Sse2.madd_epi16(interleaved, interleaved); - // - // return sqrt_epi32(radicands32); - // } - // else - // { - // if (Avx2.IsAvx2Supported) - // { - // - // } - // else - // { - // - // } - // } - //} \ No newline at end of file +//public static v128 hypot_ps(v128 a, v128 b) +//{ +// if (Constant.IsConstantExpression(a)) +// { +// return Sse.sqrt_ps(fmadd_ps(b, b, Sse.mul_ps(a, a))); +// } +// else if (Constant.IsConstantExpression(b)) +// { +// return Sse.sqrt_ps(fmadd_ps(a, a, Sse.mul_ps(b, b))); +// } +// else +// { +// return Sse.sqrt_ps(Sse.add_ps(Sse.mul_ps(a, a), Sse.mul_ps(b, b))); +// } +//} +// +// +// +// +// +//public static v128 hypot_epi16(v128 a, v128 b, byte elements = 8) +//{ +// if (elements <= 4) +// { +// v128 interleaved = Sse2.unpacklo_epi16(a, b); +// v128 radicands32 = Sse2.madd_epi16(interleaved, interleaved); +// +// return sqrt_epi32(radicands32); +// } +// else +// { +// if (Avx2.IsAvx2Supported) +// { +// +// } +// else +// { +// +// } +// } +//} \ No newline at end of file diff --git a/Runtime/__Internal/TODO/SSE2NEON.cs b/Runtime/__Internal/TODO/SSE2NEON.cs index 5b55d07..913b27c 100644 --- a/Runtime/__Internal/TODO/SSE2NEON.cs +++ b/Runtime/__Internal/TODO/SSE2NEON.cs @@ -1,4 +1,4 @@ -//using System.Runtime.CompilerServices; +//using System.Runtime.CompilerServices; //using Unity.Burst.Intrinsics; // //using static Unity.Burst.Intrinsics.X86; diff --git a/Runtime/__Internal/TODO/v16Ctors.cs b/Runtime/__Internal/TODO/v16Ctors.cs index f289dcb..f550805 100644 --- a/Runtime/__Internal/TODO/v16Ctors.cs +++ b/Runtime/__Internal/TODO/v16Ctors.cs @@ -1,9 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - namespace MaxMath { class v16Ctors diff --git a/Runtime/__Internal/Undefined.cs b/Runtime/__Internal/Uninitialized.cs similarity index 71% rename from Runtime/__Internal/Undefined.cs rename to Runtime/__Internal/Uninitialized.cs index 09ae429..d9b0aee 100644 --- a/Runtime/__Internal/Undefined.cs +++ b/Runtime/__Internal/Uninitialized.cs @@ -3,15 +3,15 @@ namespace MaxMath { - unsafe internal static class Utils + unsafe internal static class Utility { [SkipLocalsInit] [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static T Undefined() + internal static T Uninitialized() where T : unmanaged { T t; - T* dummy = &t; + T* dummyPtr = &t; return t; } diff --git a/Runtime/__Internal/Undefined.cs.meta b/Runtime/__Internal/Uninitialized.cs.meta similarity index 100% rename from Runtime/__Internal/Undefined.cs.meta rename to Runtime/__Internal/Uninitialized.cs.meta diff --git a/Runtime/__Internal/quarter/Comparison.cs b/Runtime/__Internal/quarter/Comparison.cs index a45ec9e..e6e9707 100644 --- a/Runtime/__Internal/quarter/Comparison.cs +++ b/Runtime/__Internal/quarter/Comparison.cs @@ -11,81 +11,406 @@ namespace MaxMath { internal static partial class Vectorized { + private static v128 ABS_MASK + { + get + { + if (Sse2.IsSse2Supported) + { + return Sse2.set1_epi8(unchecked((sbyte)((1 << (BITS - 1)) - 1))); + } + else throw new IllegalInstructionException(); + } + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpord_pq(v128 a, v128 b, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + if (Xse.constexpr.ALL_LT_EPU8(a, 1 << 7) && Xse.constexpr.ALL_LT_EPU8(b, 1 << 7)) + { + return Sse2.and_si128(Sse2.cmpgt_epi8(Sse2.set1_epi8(SIGNALING_EXPONENT + 1), a), + Sse2.cmpgt_epi8(Sse2.set1_epi8(SIGNALING_EXPONENT + 1), b)); + } + else + { + return Sse2.and_si128(Sse2.cmpgt_epi8(Sse2.set1_epi8(SIGNALING_EXPONENT + 1), Sse2.and_si128(a, ABS_MASK)), + Sse2.cmpgt_epi8(Sse2.set1_epi8(SIGNALING_EXPONENT + 1), Sse2.and_si128(b, ABS_MASK))); + } + + } + else throw new IllegalInstructionException(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v128 cmpeq_pq(v128 a, v128 b, byte elements = 16) + public static v128 cmpunord_pq(v128 a, v128 b, byte elements = 16) { if (Sse2.IsSse2Supported) { - v128 MASK = Sse2.set1_epi8(unchecked((sbyte)((1 << (BITS - 1)) - 1))); + if (Xse.constexpr.ALL_LT_EPU8(a, 1 << 7) && Xse.constexpr.ALL_LT_EPU8(b, 1 << 7)) + { + return Sse2.or_si128(Sse2.cmpgt_epi8(Sse2.and_si128(a, ABS_MASK), Sse2.set1_epi8(SIGNALING_EXPONENT)), + Sse2.cmpgt_epi8(Sse2.and_si128(b, ABS_MASK), Sse2.set1_epi8(SIGNALING_EXPONENT))); + } + else + { + return Sse2.or_si128(Sse2.cmpgt_epi8(a, Sse2.set1_epi8(SIGNALING_EXPONENT)), + Sse2.cmpgt_epi8(b, Sse2.set1_epi8(SIGNALING_EXPONENT))); + } + } + else throw new IllegalInstructionException(); + } - if (Xse.constexpr.ALL_EQ_EPU8(a, 0, elements)) + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpeq_pq(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + if (Xse.constexpr.ALL_EQ_EPU8(a, 0, elements) || Xse.constexpr.ALL_EQ_EPU8(a, 0b1000_0000, elements)) { - return Sse2.cmpeq_epi8(Sse2.and_si128(b, MASK), Sse2.setzero_si128()); + if (promiseNeitherNaN) + { + return Sse2.cmpeq_epi8(Xse.slli_epi8(b, 1), Sse2.setzero_si128()); + } + else + { + return Sse2.andnot_si128(cmpunord_pq(b, b), Sse2.cmpeq_epi8(Xse.slli_epi8(b, 1), Sse2.setzero_si128())); + } } - else if (Xse.constexpr.ALL_EQ_EPU8(b, 0, elements)) + else if (Xse.constexpr.ALL_EQ_EPU8(b, 0, elements) || Xse.constexpr.ALL_EQ_EPU8(b, 0b1000_0000, elements)) { - return Sse2.cmpeq_epi8(Sse2.and_si128(a, MASK), Sse2.setzero_si128()); + if (promiseNeitherNaN) + { + return Sse2.cmpeq_epi8(Xse.slli_epi8(a, 1), Sse2.setzero_si128()); + } + else + { + return Sse2.andnot_si128(cmpunord_pq(a, a), Sse2.cmpeq_epi8(Xse.slli_epi8(a, 1), Sse2.setzero_si128())); + } } else { - v128 maskeda = Sse2.and_si128(a, MASK); - v128 maskedb = Sse2.and_si128(b, MASK); + v128 equalValues = Sse2.cmpeq_epi8(a, b); - v128 nan = /*NOT!!*/Sse2.or_si128(Sse2.cmpgt_epi8(maskeda, Sse2.set1_epi8(SIGNALING_EXPONENT)), - Sse2.cmpgt_epi8(maskedb, Sse2.set1_epi8(SIGNALING_EXPONENT))); + if (promiseNeitherNaN) + { + if (promiseNeitherZero) + { + return equalValues; + } + else + { + v128 bothZero = Sse2.cmpeq_epi8(Sse2.setzero_si128(), Xse.slli_epi8(Sse2.or_si128(a, b), 1)); + + return Sse2.or_si128(bothZero, equalValues); + } + } + else + { + v128 eitherNaN = cmpunord_pq(a, b, elements); - v128 zero = Sse2.and_si128(Sse2.cmpeq_epi8(Sse2.setzero_si128(), maskeda), - Sse2.cmpeq_epi8(Sse2.setzero_si128(), maskedb)); + if (promiseNeitherZero) + { + return Sse2.andnot_si128(eitherNaN, equalValues); + } + else + { + v128 bothZero = Sse2.cmpeq_epi8(Sse2.setzero_si128(), Xse.slli_epi8(Sse2.or_si128(a, b), 1)); - v128 value = Sse2.cmpeq_epi8(a, b); + return Xse.ternarylogic_si128(eitherNaN, bothZero, equalValues, TernaryOperation.OxOE); + } + } + } + } + else throw new IllegalInstructionException(); + } - return Xse.ternarylogic_si128(nan, zero, value, TernaryOperation.OxOE); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpneq_pq(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + if (Xse.constexpr.ALL_EQ_EPU8(a, 0, elements) || Xse.constexpr.ALL_EQ_EPU8(a, 0b1000_0000, elements)) + { + if (promiseNeitherNaN) + { + return Xse.not_si128(Sse2.cmpeq_epi8(Xse.slli_epi8(b, 1), Sse2.setzero_si128())); + } + else + { + return Sse2.andnot_si128(Sse2.cmpeq_epi8(Xse.slli_epi8(b, 1), Sse2.setzero_si128()), cmpord_pq(b, b)); + } + } + else if (Xse.constexpr.ALL_EQ_EPU8(b, 0, elements) || Xse.constexpr.ALL_EQ_EPU8(b, 0b1000_0000, elements)) + { + if (promiseNeitherNaN) + { + return Xse.not_si128(Sse2.cmpeq_epi8(Xse.slli_epi8(a, 1), Sse2.setzero_si128())); + } + else + { + return Sse2.andnot_si128(Sse2.cmpeq_epi8(Xse.slli_epi8(a, 1), Sse2.setzero_si128()), cmpord_pq(a, a)); + } + } + else + { + v128 equalValues = Sse2.cmpeq_epi8(a, b); + + if (promiseNeitherNaN) + { + if (promiseNeitherZero) + { + return Xse.not_si128(equalValues); + } + else + { + v128 bothZero = Sse2.cmpeq_epi8(Sse2.setzero_si128(), Xse.slli_epi8(Sse2.or_si128(a, b), 1)); + + return Xse.nor_si128(equalValues, bothZero); + } + } + else + { + v128 eitherNaN = cmpunord_pq(a, b, elements); + + if (promiseNeitherZero) + { + return Xse.ornot_si128(equalValues, eitherNaN); + } + else + { + v128 bothZero = Sse2.cmpeq_epi8(Sse2.setzero_si128(), Xse.slli_epi8(Sse2.or_si128(a, b), 1)); + + return Xse.ternarylogic_si128(eitherNaN, bothZero, equalValues, TernaryOperation.OxF1); + } + } } } else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static v128 cmpneq_pq(v128 a, v128 b, byte elements = 16) + public static v128 cmplt_pq(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 16) { if (Sse2.IsSse2Supported) { - v128 MASK = Sse2.set1_epi8(unchecked((sbyte)((1 << (BITS - 1)) - 1))); + if (Xse.constexpr.ALL_EQ_EPU8(b, 0, elements) || Xse.constexpr.ALL_EQ_EPU8(b, 0b1000_0000, elements)) + { + v128 negative = Sse2.cmpgt_epi8(Sse2.setzero_si128(), a); + v128 zero = Sse2.cmpeq_epi8(Sse2.setzero_si128(), Xse.slli_epi8(a, 1)); + + if (promiseNeitherNaN) + { + return Sse2.andnot_si128(zero, negative); + } + else + { + return Xse.ternarylogic_si128(cmpunord_pq(a, a), zero, negative, TernaryOperation.OxO2); + } + } + if (Xse.constexpr.ALL_EQ_EPU8(a, 0, elements) || Xse.constexpr.ALL_EQ_EPU8(a, 0b1000_0000, elements)) + { + v128 positive = Sse2.cmpgt_epi8(b, Sse2.setzero_si128()); + v128 zero = Sse2.cmpeq_epi8(Sse2.setzero_si128(), Xse.slli_epi8(b, 1)); + + if (promiseNeitherNaN) + { + return Sse2.andnot_si128(zero, positive); + } + else + { + return Xse.ternarylogic_si128(cmpunord_pq(b, b), zero, positive, TernaryOperation.OxO2); + } + } + + + v128 equalValues = Sse2.cmpeq_epi8(a, b); + + v128 signA = Xse.srai_epi8(a, 7); + v128 signB = Xse.srai_epi8(b, 7); + v128 equalSigns = Sse2.cmpeq_epi8(signA, signB); + v128 ifEqualSigns; + //if (Avx512.IsAvx512Supported) + //{ + // ifEqualSigns = Xse.ternarylogic_si128(equalValues, signA, Xse.cmple_epu8(b, a, elements), TernaryOperation.OxO9); + //} + //else + //{ + ifEqualSigns = Xse.ternarylogic_si128(equalValues, signA, Xse.cmpgt_epu8(b, a, elements), TernaryOperation.OxO6); + //} - if (Xse.constexpr.ALL_EQ_EPU8(a, 0, elements)) + v128 orderedCmp; + if (promiseNeitherZero) { - return Xse.not_si128(Sse2.cmpeq_epi8(Sse2.and_si128(b, MASK), Sse2.setzero_si128())); + orderedCmp = Xse.blendv_si128(signA, ifEqualSigns, equalSigns); } - else if (Xse.constexpr.ALL_EQ_EPU8(b, 0, elements)) + else { - return Xse.not_si128(Sse2.cmpeq_epi8(Sse2.and_si128(a, MASK), Sse2.setzero_si128())); - } + v128 bothZero = Sse2.cmpeq_epi8(Sse2.setzero_si128(), Xse.slli_epi8(Sse2.or_si128(a, b), 1)); + v128 ifOppositeSigns = Sse2.andnot_si128(bothZero, signA); + orderedCmp = Xse.blendv_si128(ifOppositeSigns, ifEqualSigns, equalSigns); + } + + if (promiseNeitherNaN) + { + return orderedCmp; + } else { - v128 maskedLeft = Sse2.and_si128(a, MASK); - v128 maskedRight = Sse2.and_si128(b, MASK); + v128 eitherNaN = cmpunord_pq(a, b, elements); - v128 nan = Sse2.or_si128(Sse2.cmpgt_epi8(maskedLeft, Sse2.set1_epi8(SIGNALING_EXPONENT)), - Sse2.cmpgt_epi8(maskedRight, Sse2.set1_epi8(SIGNALING_EXPONENT))); + return Sse2.andnot_si128(eitherNaN, orderedCmp); + } + } + else throw new IllegalInstructionException(); + } - v128 zero = /*NOT!!*/Sse2.and_si128(Sse2.cmpeq_epi8(Sse2.setzero_si128(), maskedLeft), - Sse2.cmpeq_epi8(Sse2.setzero_si128(), maskedRight)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpgt_pq(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + return cmplt_pq(b, a, promiseNeitherNaN, promiseNeitherZero, elements); + } + else throw new IllegalInstructionException(); + } - v128 value = /*NOT!!*/Sse2.cmpeq_epi8(a, b); - - return Xse.ternarylogic_si128(nan, zero, value, TernaryOperation.OxF1); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmple_pq(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + if (Xse.constexpr.ALL_EQ_EPU8(b, 0, elements) || Xse.constexpr.ALL_EQ_EPU8(b, 0b1000_0000, elements)) + { + v128 intLEzero = Sse2.cmpgt_epi8(Sse2.set1_epi8(1), a); + + if (promiseNeitherNaN) + { + return intLEzero; + } + else + { + return Sse2.andnot_si128(cmpunord_pq(a, a), intLEzero); + } } + if (Xse.constexpr.ALL_EQ_EPU8(a, 0, elements) || Xse.constexpr.ALL_EQ_EPU8(a, 0b1000_0000, elements)) + { + v128 uintGEzero = Sse2.cmpgt_epi8(b, Sse2.setzero_si128()); + v128 negativeZero = Sse2.cmpeq_epi8(b, Sse2.set1_epi8(unchecked((sbyte)(1 << 7)))); + + if (promiseNeitherNaN) + { + return Sse2.or_si128(uintGEzero, negativeZero); + } + else + { + return Xse.ternarylogic_si128(cmpunord_pq(b, b), uintGEzero, negativeZero, TernaryOperation.OxOE); + } + } + + + v128 equalValues = Sse2.cmpeq_epi8(a, b); + + v128 signA = Xse.srai_epi8(a, 7); + v128 signB = Xse.srai_epi8(b, 7); + v128 equalSigns = Sse2.cmpeq_epi8(signA, signB); + v128 ifEqualSigns; + //if (Avx512.IsAvx512Supported) + //{ + // ifEqualSigns = Xse.ternarylogic_si128(equalValues, signA, Xse.cmple_epu8(b, a, elements), TernaryOperation.OxF9); + //} + //else + //{ + ifEqualSigns = Xse.ternarylogic_si128(equalValues, signA, Xse.cmpgt_epu8(b, a, elements), TernaryOperation.OxF6); + //} + + v128 orderedCmp; + if (promiseNeitherZero) + { + orderedCmp = Xse.blendv_si128(Xse.setall_si128(), ifEqualSigns, equalSigns); + } + else + { + v128 bothZero = Sse2.cmpeq_epi8(Sse2.setzero_si128(), Xse.slli_epi8(Sse2.or_si128(a, b), 1)); + v128 ifOppositeSigns = Sse2.or_si128(bothZero, signA); + orderedCmp = Xse.blendv_si128(ifOppositeSigns, ifEqualSigns, equalSigns); + } + + if (promiseNeitherNaN) + { + return orderedCmp; + } + else + { + v128 eitherNaN = cmpunord_pq(a, b, elements); + + return Sse2.andnot_si128(eitherNaN, orderedCmp); + } + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpge_pq(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + return cmple_pq(b, a, promiseNeitherNaN, promiseNeitherZero, elements); + } + else throw new IllegalInstructionException(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpngt_pq(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + return cmple_pq(b, a, promiseNeitherNaN, promiseNeitherZero, elements); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpnlt_pq(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + return cmpge_pq(b, a, promiseNeitherNaN, promiseNeitherZero, elements); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpnge_pq(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + return cmplt_pq(b, a, promiseNeitherNaN, promiseNeitherZero, elements); + } + else throw new IllegalInstructionException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static v128 cmpnle_pq(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 16) + { + if (Sse2.IsSse2Supported) + { + return cmpgt_pq(b, a, promiseNeitherNaN, promiseNeitherZero, elements); } else throw new IllegalInstructionException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool vcmpeq_pq(v128 a, v128 b, byte elements = 16) + public static bool vcmpeq_pq(v128 a, v128 b, bool promiseNeitherNaN = false, bool promiseNeitherZero = false, byte elements = 16) { if (Sse2.IsSse2Supported) { - return Xse.alltrue_epi128(cmpeq_pq(a, b, elements), elements); + return Xse.alltrue_epi128(cmpeq_pq(a, b, promiseNeitherNaN, promiseNeitherZero, elements), elements); } else throw new IllegalInstructionException(); } diff --git a/Runtime/__Internal/quarter/Floating Point Conversion.cs b/Runtime/__Internal/quarter/Floating Point Conversion.cs index ebd5caf..3f37a78 100644 --- a/Runtime/__Internal/quarter/Floating Point Conversion.cs +++ b/Runtime/__Internal/quarter/Floating Point Conversion.cs @@ -226,7 +226,7 @@ public static v128 cvtph_pq(v128 h, bool promiseInRange = false, bool promiseAbs { if (elements == 8) { - float8 f = RegisterConversion.ToType(h); + float8 f = (half8)h; if (Avx2.IsAvx2Supported) { @@ -239,19 +239,19 @@ public static v128 cvtph_pq(v128 h, bool promiseInRange = false, bool promiseAbs } else if (elements == 4) { - float4 f = RegisterConversion.ToType(h); + float4 f = RegisterConversion.ToHalf4(h); return cvtps_pq(RegisterConversion.ToV128(f), promiseInRange: promiseInRange, promiseAbsoluteAndInRange: promiseAbsolute & promiseInRange, elements: 4); } else if (elements == 3) { - float3 f = RegisterConversion.ToType(h); + float3 f = RegisterConversion.ToHalf3(h); return cvtps_pq(RegisterConversion.ToV128(f), promiseInRange: promiseInRange, promiseAbsoluteAndInRange: promiseAbsolute & promiseInRange, elements: 3); } else { - float2 f = RegisterConversion.ToType(h); + float2 f = RegisterConversion.ToHalf2(h); return cvtps_pq(RegisterConversion.ToV128(f), promiseInRange: promiseInRange, promiseAbsoluteAndInRange: promiseAbsolute & promiseInRange, elements: 2); } diff --git a/Tests/AssemblyInfo.cs b/Tests/AssemblyInfo.cs index 42e7e4b..4d608d4 100644 --- a/Tests/AssemblyInfo.cs +++ b/Tests/AssemblyInfo.cs @@ -1,4 +1,3 @@ -using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.InteropServices; diff --git a/Tests/Editor/Functions/Arithmetic/Integer/comb.cs b/Tests/Editor/Functions/Arithmetic/Integer/comb.cs new file mode 100644 index 0000000..85901a3 --- /dev/null +++ b/Tests/Editor/Functions/Arithmetic/Integer/comb.cs @@ -0,0 +1,2247 @@ +using NUnit.Framework; +using Unity.Mathematics; + +using static Unity.Burst.Intrinsics.X86; + +namespace MaxMath.Tests +{ + unsafe public static class comb + { + private static UInt128 realbinom(UInt128 n, UInt128 k) + { + UInt128 c = 1; + + if (k > n - k) + k = n - k; + + for (UInt128 i = 1; i <= k; i++, n--) + { + c = c / i * n + c % i * n / i; + } + + return c; + } + + private static ulong realbinom(ulong n, ulong k) + { + ulong c = 1; + + if (k > n - k) + k = n - k; + + for (ulong i = 1; i <= k; i++, n--) + { + c = c / i * n + c % i * n / i; + } + + return c; + } + + private static uint realbinom(uint n, uint k) + { + uint c = 1; + + if (k > n - k) + k = n - k; + + for (uint i = 1; i <= k; i++, n--) + { + c = c / i * n + c % i * n / i; + } + + return c; + } + + private static ushort realbinom(ushort n, ushort k) + { + ushort c = 1; + + if (k > n - k) + k = (ushort)(n - k); + + for (ushort i = 1; i <= k; i++, n--) + { + c = (ushort)((ushort)((ushort)(c / i) * n) + (ushort)((ushort)((ushort)(c % i) * n) / i)); + } + + return c; + } + + private static byte realbinom(byte n, byte k) + { + byte c = 1; + + if (k > n - k) + k = (byte)(n - k); + + for (byte i = 1; i <= k; i++, n--) + { + c = (byte)((byte)((byte)(c / i) * n) + (byte)((byte)((byte)(c % i) * n) / i)); + } + + return c; + } + + + [Test] + public static void _uint128() + { + Random128 rng = Random128.New; + + for (int i = 0; i < 8; i++) + { + UInt128 n = rng.NextUInt128(1, UInt128.MaxValue); + UInt128 k = n - 1; + + Assert.AreEqual(maxmath.comb(n, k), n); + + n = rng.NextUInt128(1, UInt128.MaxValue); + k = rng.NextUInt128(0, n + 1); + k = maxmath.select(k, n - 100, n - k > 100); + + Assert.AreEqual(maxmath.comb((UInt128)n, (UInt128)k), realbinom((UInt128)n, (UInt128)k)); + Assert.AreEqual(maxmath.comb((UInt128)n, (UInt128)0), realbinom((UInt128)n, (UInt128)0)); + Assert.AreEqual(maxmath.comb((UInt128)n, (UInt128)1), realbinom((UInt128)n, (UInt128)1)); + Assert.AreEqual(maxmath.comb((UInt128)1, (UInt128)0), realbinom((UInt128)1, (UInt128)0)); + Assert.AreEqual(maxmath.comb((UInt128)1, (UInt128)1), realbinom((UInt128)1, (UInt128)1)); + } + } + + + [Test] + public static void _byte2() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 18; i++) + { + byte2 n = rng.NextByte2(1, 64); + byte2 k = n - 1; + byte2 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, n.x); + Assert.AreEqual(c.y, n.y); + + n = rng.NextByte2(1, byte.MaxValue); + k = rng.NextByte2(0, maxmath.min(rng.NextByte2(1, byte.MaxValue), maxmath.subsaturated(n, 25))); + + if (Sse2.IsSse2Supported) + { + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, k.x)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, k.y)); + + c = maxmath.comb(n, 0); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, 0)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, 0)); + + c = maxmath.comb(n, new byte2(0, 1)); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, 0)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, 1)); + + c = maxmath.comb(n, new byte2(k.x, 1)); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, k.x)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, 1)); + + c = maxmath.comb(n, new byte2(k.x, 0)); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, k.x)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, 1)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, 1)); + + c = maxmath.comb(new byte2(1), new byte2(0)); + Assert.AreEqual(c.x, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)1, 0)); + + c = maxmath.comb(new byte2(1), new byte2(1)); + Assert.AreEqual(c.x, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)1, 1)); + } + else + { + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, k.y)); + + c = maxmath.comb(n, 0); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + + c = maxmath.comb(n, new byte2(0, 1)); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + + c = maxmath.comb(n, new byte2(k.x, 1)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + + c = maxmath.comb(n, new byte2(k.x, 0)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x, realbinom(n.x, 1)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + + c = maxmath.comb(new byte2(1), new byte2(0)); + Assert.AreEqual(c.x, realbinom(1, 0)); + Assert.AreEqual(c.y, realbinom(1, 0)); + + c = maxmath.comb(new byte2(1), new byte2(1)); + Assert.AreEqual(c.x, realbinom(1, 1)); + Assert.AreEqual(c.y, realbinom(1, 1)); + } + } + } + + [Test] + public static void _byte3() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 16; i++) + { + byte3 n = rng.NextByte3(1, 64); + byte3 k = n - 1; + byte3 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, n.x); + Assert.AreEqual(c.y, n.y); + Assert.AreEqual(c.z, n.z); + + n = rng.NextByte3(1, byte.MaxValue); + k = rng.NextByte3(0, maxmath.min(rng.NextByte3(1, byte.MaxValue), maxmath.subsaturated(n, 25))); + + if (Sse2.IsSse2Supported) + { + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, k.x)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, k.y)); + Assert.AreEqual(c.z, (byte)realbinom((ushort)n.z, k.z)); + + c = maxmath.comb(n, 0); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, 0)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, 0)); + Assert.AreEqual(c.z, (byte)realbinom((ushort)n.z, 0)); + + c = maxmath.comb(n, new byte3(0, 1, 0)); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, 0)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, 1)); + Assert.AreEqual(c.z, (byte)realbinom((ushort)n.z, 0)); + + c = maxmath.comb(n, new byte3(k.x, 1, k.z)); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, k.x)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, 1)); + Assert.AreEqual(c.z, (byte)realbinom((ushort)n.z, k.z)); + + c = maxmath.comb(n, new byte3(k.x, 0, k.z)); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, k.x)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, 0)); + Assert.AreEqual(c.z, (byte)realbinom((ushort)n.z, k.z)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, 1)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, 1)); + Assert.AreEqual(c.z, (byte)realbinom((ushort)n.z, 1)); + + c = maxmath.comb(new byte3(1), new byte3(0)); + Assert.AreEqual(c.x, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.z, (byte)realbinom((ushort)1, 0)); + + c = maxmath.comb(new byte3(1), new byte3(1)); + Assert.AreEqual(c.x, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.z, (byte)realbinom((ushort)1, 1)); + } + else + { + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, k.y)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + + c = maxmath.comb(n, 0); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + Assert.AreEqual(c.z, realbinom(n.z, 0)); + + c = maxmath.comb(n, new byte3(0, 1, 0)); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 0)); + + c = maxmath.comb(n, new byte3(k.x, 1, k.z)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + + c = maxmath.comb(n, new byte3(k.x, 0, k.z)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x, realbinom(n.x, 1)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 1)); + + c = maxmath.comb(new byte3(1), new byte3(0)); + Assert.AreEqual(c.x, realbinom(1, 0)); + Assert.AreEqual(c.y, realbinom(1, 0)); + Assert.AreEqual(c.z, realbinom(1, 0)); + + c = maxmath.comb(new byte3(1), new byte3(1)); + Assert.AreEqual(c.x, realbinom(1, 1)); + Assert.AreEqual(c.y, realbinom(1, 1)); + Assert.AreEqual(c.z, realbinom(1, 1)); + } + } + } + + [Test] + public static void _byte4() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 14; i++) + { + byte4 n = rng.NextByte4(1, 64); + byte4 k = n - 1; + byte4 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, n.x); + Assert.AreEqual(c.y, n.y); + Assert.AreEqual(c.z, n.z); + Assert.AreEqual(c.w, n.w); + + n = rng.NextByte4(1, byte.MaxValue); + k = rng.NextByte4(0, maxmath.min(rng.NextByte4(1, byte.MaxValue), maxmath.subsaturated(n, 25))); + + if (Sse2.IsSse2Supported) + { + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, k.x)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, k.y)); + Assert.AreEqual(c.z, (byte)realbinom((ushort)n.z, k.z)); + Assert.AreEqual(c.w, (byte)realbinom((ushort)n.w, k.w)); + + c = maxmath.comb(n, k); + Assert.AreEqual(maxmath.comb(n, 0).x, (byte)realbinom((ushort)n.x, 0)); + Assert.AreEqual(maxmath.comb(n, 0).y, (byte)realbinom((ushort)n.y, 0)); + Assert.AreEqual(maxmath.comb(n, 0).z, (byte)realbinom((ushort)n.z, 0)); + Assert.AreEqual(maxmath.comb(n, 0).w, (byte)realbinom((ushort)n.w, 0)); + + c = maxmath.comb(n, new byte4(0, 1, 0, 1)); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, 0)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, 1)); + Assert.AreEqual(c.z, (byte)realbinom((ushort)n.z, 0)); + Assert.AreEqual(c.w, (byte)realbinom((ushort)n.w, 1)); + + c = maxmath.comb(n, new byte4(k.x, 1, k.z, 1)); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, k.x)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, 1)); + Assert.AreEqual(c.z, (byte)realbinom((ushort)n.z, k.z)); + Assert.AreEqual(c.w, (byte)realbinom((ushort)n.w, 1)); + + c = maxmath.comb(n, new byte4(k.x, 0, k.z, 0)); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, k.x)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, 0)); + Assert.AreEqual(c.z, (byte)realbinom((ushort)n.z, k.z)); + Assert.AreEqual(c.w, (byte)realbinom((ushort)n.w, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x, (byte)realbinom((ushort)n.x, 1)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)n.y, 1)); + Assert.AreEqual(c.z, (byte)realbinom((ushort)n.z, 1)); + Assert.AreEqual(c.w, (byte)realbinom((ushort)n.w, 1)); + + c = maxmath.comb(new byte4(1), new byte4(0)); + Assert.AreEqual(c.x, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.z, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.w, (byte)realbinom((ushort)1, 0)); + + c = maxmath.comb(new byte4(1), new byte4(1)); + Assert.AreEqual(c.x, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.y, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.z, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.w, (byte)realbinom((ushort)1, 1)); + } + else + { + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, k.y)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + Assert.AreEqual(c.w, realbinom(n.w, k.w)); + + c = maxmath.comb(n, k); + Assert.AreEqual(maxmath.comb(n, 0).x, realbinom(n.x, 0)); + Assert.AreEqual(maxmath.comb(n, 0).y, realbinom(n.y, 0)); + Assert.AreEqual(maxmath.comb(n, 0).z, realbinom(n.z, 0)); + Assert.AreEqual(maxmath.comb(n, 0).w, realbinom(n.w, 0)); + + c = maxmath.comb(n, new byte4(0, 1, 0, 1)); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 0)); + Assert.AreEqual(c.w, realbinom(n.w, 1)); + + c = maxmath.comb(n, new byte4(k.x, 1, k.z, 1)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + Assert.AreEqual(c.w, realbinom(n.w, 1)); + + c = maxmath.comb(n, new byte4(k.x, 0, k.z, 0)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + Assert.AreEqual(c.w, realbinom(n.w, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x, realbinom(n.x, 1)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 1)); + Assert.AreEqual(c.w, realbinom(n.w, 1)); + + c = maxmath.comb(new byte4(1), new byte4(0)); + Assert.AreEqual(c.x, realbinom(1, 0)); + Assert.AreEqual(c.y, realbinom(1, 0)); + Assert.AreEqual(c.z, realbinom(1, 0)); + Assert.AreEqual(c.w, realbinom(1, 0)); + + c = maxmath.comb(new byte4(1), new byte4(1)); + Assert.AreEqual(c.x, realbinom(1, 1)); + Assert.AreEqual(c.y, realbinom(1, 1)); + Assert.AreEqual(c.z, realbinom(1, 1)); + Assert.AreEqual(c.w, realbinom(1, 1)); + } + } + } + + [Test] + public static void _byte8() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 12; i++) + { + byte8 n = rng.NextByte8(1, 64); + byte8 k = n - 1; + byte8 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x0, n.x0); + Assert.AreEqual(c.x1, n.x1); + Assert.AreEqual(c.x2, n.x2); + Assert.AreEqual(c.x3, n.x3); + Assert.AreEqual(c.x4, n.x4); + Assert.AreEqual(c.x5, n.x5); + Assert.AreEqual(c.x6, n.x6); + Assert.AreEqual(c.x7, n.x7); + + n = rng.NextByte8(1, byte.MaxValue); + k = rng.NextByte8(0, maxmath.min(rng.NextByte8(1, byte.MaxValue), maxmath.subsaturated(n, 25))); + + if (Sse2.IsSse2Supported) + { + c = maxmath.comb(n, k); + Assert.AreEqual(c.x0, (byte)realbinom((ushort)n.x0, k.x0)); + Assert.AreEqual(c.x1, (byte)realbinom((ushort)n.x1, k.x1)); + Assert.AreEqual(c.x2, (byte)realbinom((ushort)n.x2, k.x2)); + Assert.AreEqual(c.x3, (byte)realbinom((ushort)n.x3, k.x3)); + Assert.AreEqual(c.x4, (byte)realbinom((ushort)n.x4, k.x4)); + Assert.AreEqual(c.x5, (byte)realbinom((ushort)n.x5, k.x5)); + Assert.AreEqual(c.x6, (byte)realbinom((ushort)n.x6, k.x6)); + Assert.AreEqual(c.x7, (byte)realbinom((ushort)n.x7, k.x7)); + + c = maxmath.comb(n, k); + Assert.AreEqual(maxmath.comb(n, 0).x0, (byte)realbinom((ushort)n.x0, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x1, (byte)realbinom((ushort)n.x1, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x2, (byte)realbinom((ushort)n.x2, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x3, (byte)realbinom((ushort)n.x3, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x4, (byte)realbinom((ushort)n.x4, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x5, (byte)realbinom((ushort)n.x5, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x6, (byte)realbinom((ushort)n.x6, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x7, (byte)realbinom((ushort)n.x7, 0)); + + c = maxmath.comb(n, new byte8(0, 1, 0, 1, 0, 1, 0, 1)); + Assert.AreEqual(c.x0, (byte)realbinom((ushort)n.x0, 0)); + Assert.AreEqual(c.x1, (byte)realbinom((ushort)n.x1, 1)); + Assert.AreEqual(c.x2, (byte)realbinom((ushort)n.x2, 0)); + Assert.AreEqual(c.x3, (byte)realbinom((ushort)n.x3, 1)); + Assert.AreEqual(c.x4, (byte)realbinom((ushort)n.x4, 0)); + Assert.AreEqual(c.x5, (byte)realbinom((ushort)n.x5, 1)); + Assert.AreEqual(c.x6, (byte)realbinom((ushort)n.x6, 0)); + Assert.AreEqual(c.x7, (byte)realbinom((ushort)n.x7, 1)); + + c = maxmath.comb(n, new byte8(k.x0, 1, k.x2, 1, k.x4, 1, k.x6, 1)); + Assert.AreEqual(c.x0, (byte)realbinom((ushort)n.x0, k.x0)); + Assert.AreEqual(c.x1, (byte)realbinom((ushort)n.x1, 1)); + Assert.AreEqual(c.x2, (byte)realbinom((ushort)n.x2, k.x2)); + Assert.AreEqual(c.x3, (byte)realbinom((ushort)n.x3, 1)); + Assert.AreEqual(c.x4, (byte)realbinom((ushort)n.x4, k.x4)); + Assert.AreEqual(c.x5, (byte)realbinom((ushort)n.x5, 1)); + Assert.AreEqual(c.x6, (byte)realbinom((ushort)n.x6, k.x6)); + Assert.AreEqual(c.x7, (byte)realbinom((ushort)n.x7, 1)); + + c = maxmath.comb(n, new byte8(k.x0, 0, k.x2, 0, k.x4, 0, k.x6, 0)); + Assert.AreEqual(c.x0, (byte)realbinom((ushort)n.x0, k.x0)); + Assert.AreEqual(c.x1, (byte)realbinom((ushort)n.x1, 0)); + Assert.AreEqual(c.x2, (byte)realbinom((ushort)n.x2, k.x2)); + Assert.AreEqual(c.x3, (byte)realbinom((ushort)n.x3, 0)); + Assert.AreEqual(c.x4, (byte)realbinom((ushort)n.x4, k.x4)); + Assert.AreEqual(c.x5, (byte)realbinom((ushort)n.x5, 0)); + Assert.AreEqual(c.x6, (byte)realbinom((ushort)n.x6, k.x6)); + Assert.AreEqual(c.x7, (byte)realbinom((ushort)n.x7, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x0, (byte)realbinom((ushort)n.x0, 1)); + Assert.AreEqual(c.x1, (byte)realbinom((ushort)n.x1, 1)); + Assert.AreEqual(c.x2, (byte)realbinom((ushort)n.x2, 1)); + Assert.AreEqual(c.x3, (byte)realbinom((ushort)n.x3, 1)); + Assert.AreEqual(c.x4, (byte)realbinom((ushort)n.x4, 1)); + Assert.AreEqual(c.x5, (byte)realbinom((ushort)n.x5, 1)); + Assert.AreEqual(c.x6, (byte)realbinom((ushort)n.x6, 1)); + Assert.AreEqual(c.x7, (byte)realbinom((ushort)n.x7, 1)); + + c = maxmath.comb(new byte8(1), new byte8(0)); + Assert.AreEqual(c.x0, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x1, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x2, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x3, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x4, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x5, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x6, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x7, (byte)realbinom((ushort)1, 0)); + + c = maxmath.comb(new byte8(1), new byte8(1)); + Assert.AreEqual(c.x0, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x1, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x2, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x3, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x4, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x5, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x6, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x7, (byte)realbinom((ushort)1, 1)); + } + else + { + c = maxmath.comb(n, k); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, k.x1)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, k.x3)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, k.x5)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, k.x7)); + + c = maxmath.comb(n, k); + Assert.AreEqual(maxmath.comb(n, 0).x0, realbinom(n.x0, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x1, realbinom(n.x1, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x2, realbinom(n.x2, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x3, realbinom(n.x3, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x4, realbinom(n.x4, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x5, realbinom(n.x5, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x6, realbinom(n.x6, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x7, realbinom(n.x7, 0)); + + c = maxmath.comb(n, new byte8(0, 1, 0, 1, 0, 1, 0, 1)); + Assert.AreEqual(c.x0, realbinom(n.x0, 0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, 0)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, 0)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, 0)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + + c = maxmath.comb(n, new byte8(k.x0, 1, k.x2, 1, k.x4, 1, k.x6, 1)); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + + c = maxmath.comb(n, new byte8(k.x0, 0, k.x2, 0, k.x4, 0, k.x6, 0)); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 0)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, 0)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, 0)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x0, realbinom(n.x0, 1)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, 1)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, 1)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, 1)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + + c = maxmath.comb(new byte8(1), new byte8(0)); + Assert.AreEqual(c.x0, realbinom(1, 0)); + Assert.AreEqual(c.x1, realbinom(1, 0)); + Assert.AreEqual(c.x2, realbinom(1, 0)); + Assert.AreEqual(c.x3, realbinom(1, 0)); + Assert.AreEqual(c.x4, realbinom(1, 0)); + Assert.AreEqual(c.x5, realbinom(1, 0)); + Assert.AreEqual(c.x6, realbinom(1, 0)); + Assert.AreEqual(c.x7, realbinom(1, 0)); + + c = maxmath.comb(new byte8(1), new byte8(1)); + Assert.AreEqual(c.x0, realbinom(1, 1)); + Assert.AreEqual(c.x1, realbinom(1, 1)); + Assert.AreEqual(c.x2, realbinom(1, 1)); + Assert.AreEqual(c.x3, realbinom(1, 1)); + Assert.AreEqual(c.x4, realbinom(1, 1)); + Assert.AreEqual(c.x5, realbinom(1, 1)); + Assert.AreEqual(c.x6, realbinom(1, 1)); + Assert.AreEqual(c.x7, realbinom(1, 1)); + } + } + } + + [Test] + public static void _byte16() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 10; i++) + { + byte16 n = rng.NextByte16(1, 64); + byte16 k = n - 1; + byte16 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x0, n.x0); + Assert.AreEqual(c.x1, n.x1); + Assert.AreEqual(c.x2, n.x2); + Assert.AreEqual(c.x3, n.x3); + Assert.AreEqual(c.x4, n.x4); + Assert.AreEqual(c.x5, n.x5); + Assert.AreEqual(c.x6, n.x6); + Assert.AreEqual(c.x7, n.x7); + Assert.AreEqual(c.x8, n.x8); + Assert.AreEqual(c.x9, n.x9); + Assert.AreEqual(c.x10, n.x10); + Assert.AreEqual(c.x11, n.x11); + Assert.AreEqual(c.x12, n.x12); + Assert.AreEqual(c.x13, n.x13); + Assert.AreEqual(c.x14, n.x14); + Assert.AreEqual(c.x15, n.x15); + + n = rng.NextByte16(1, byte.MaxValue); + k = rng.NextByte16(0, maxmath.min(rng.NextByte16(1, byte.MaxValue), maxmath.subsaturated(n, 25))); + + if (Avx2.IsAvx2Supported) + { + c = maxmath.comb(n, k); + Assert.AreEqual(c.x0, (byte)realbinom((ushort)n.x0, k.x0)); + Assert.AreEqual(c.x1, (byte)realbinom((ushort)n.x1, k.x1)); + Assert.AreEqual(c.x2, (byte)realbinom((ushort)n.x2, k.x2)); + Assert.AreEqual(c.x3, (byte)realbinom((ushort)n.x3, k.x3)); + Assert.AreEqual(c.x4, (byte)realbinom((ushort)n.x4, k.x4)); + Assert.AreEqual(c.x5, (byte)realbinom((ushort)n.x5, k.x5)); + Assert.AreEqual(c.x6, (byte)realbinom((ushort)n.x6, k.x6)); + Assert.AreEqual(c.x7, (byte)realbinom((ushort)n.x7, k.x7)); + Assert.AreEqual(c.x8, (byte)realbinom((ushort)n.x8, k.x8)); + Assert.AreEqual(c.x9, (byte)realbinom((ushort)n.x9, k.x9)); + Assert.AreEqual(c.x10, (byte)realbinom((ushort)n.x10, k.x10)); + Assert.AreEqual(c.x11, (byte)realbinom((ushort)n.x11, k.x11)); + Assert.AreEqual(c.x12, (byte)realbinom((ushort)n.x12, k.x12)); + Assert.AreEqual(c.x13, (byte)realbinom((ushort)n.x13, k.x13)); + Assert.AreEqual(c.x14, (byte)realbinom((ushort)n.x14, k.x14)); + Assert.AreEqual(c.x15, (byte)realbinom((ushort)n.x15, k.x15)); + + c = maxmath.comb(n, k); + Assert.AreEqual(maxmath.comb(n, 0).x0, (byte)realbinom((ushort)n.x0, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x1, (byte)realbinom((ushort)n.x1, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x2, (byte)realbinom((ushort)n.x2, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x3, (byte)realbinom((ushort)n.x3, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x4, (byte)realbinom((ushort)n.x4, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x5, (byte)realbinom((ushort)n.x5, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x6, (byte)realbinom((ushort)n.x6, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x7, (byte)realbinom((ushort)n.x7, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x8, (byte)realbinom((ushort)n.x8, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x9, (byte)realbinom((ushort)n.x9, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x10, (byte)realbinom((ushort)n.x10, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x11, (byte)realbinom((ushort)n.x11, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x12, (byte)realbinom((ushort)n.x12, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x13, (byte)realbinom((ushort)n.x13, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x14, (byte)realbinom((ushort)n.x14, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x15, (byte)realbinom((ushort)n.x15, 0)); + + c = maxmath.comb(n, new byte16(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)); + Assert.AreEqual(c.x0, (byte)realbinom((ushort)n.x0, 0)); + Assert.AreEqual(c.x1, (byte)realbinom((ushort)n.x1, 1)); + Assert.AreEqual(c.x2, (byte)realbinom((ushort)n.x2, 0)); + Assert.AreEqual(c.x3, (byte)realbinom((ushort)n.x3, 1)); + Assert.AreEqual(c.x4, (byte)realbinom((ushort)n.x4, 0)); + Assert.AreEqual(c.x5, (byte)realbinom((ushort)n.x5, 1)); + Assert.AreEqual(c.x6, (byte)realbinom((ushort)n.x6, 0)); + Assert.AreEqual(c.x7, (byte)realbinom((ushort)n.x7, 1)); + Assert.AreEqual(c.x8, (byte)realbinom((ushort)n.x8, 0)); + Assert.AreEqual(c.x9, (byte)realbinom((ushort)n.x9, 1)); + Assert.AreEqual(c.x10, (byte)realbinom((ushort)n.x10, 0)); + Assert.AreEqual(c.x11, (byte)realbinom((ushort)n.x11, 1)); + Assert.AreEqual(c.x12, (byte)realbinom((ushort)n.x12, 0)); + Assert.AreEqual(c.x13, (byte)realbinom((ushort)n.x13, 1)); + Assert.AreEqual(c.x14, (byte)realbinom((ushort)n.x14, 0)); + Assert.AreEqual(c.x15, (byte)realbinom((ushort)n.x15, 1)); + + c = maxmath.comb(n, new byte16(k.x0, 1, k.x2, 1, k.x4, 1, k.x6, 1, k.x8, 1, k.x10, 1, k.x12, 1, k.x14, 1)); + Assert.AreEqual(c.x0, (byte)realbinom((ushort)n.x0, k.x0)); + Assert.AreEqual(c.x1, (byte)realbinom((ushort)n.x1, 1)); + Assert.AreEqual(c.x2, (byte)realbinom((ushort)n.x2, k.x2)); + Assert.AreEqual(c.x3, (byte)realbinom((ushort)n.x3, 1)); + Assert.AreEqual(c.x4, (byte)realbinom((ushort)n.x4, k.x4)); + Assert.AreEqual(c.x5, (byte)realbinom((ushort)n.x5, 1)); + Assert.AreEqual(c.x6, (byte)realbinom((ushort)n.x6, k.x6)); + Assert.AreEqual(c.x7, (byte)realbinom((ushort)n.x7, 1)); + Assert.AreEqual(c.x8, (byte)realbinom((ushort)n.x8, k.x8)); + Assert.AreEqual(c.x9, (byte)realbinom((ushort)n.x9, 1)); + Assert.AreEqual(c.x10, (byte)realbinom((ushort)n.x10, k.x10)); + Assert.AreEqual(c.x11, (byte)realbinom((ushort)n.x11, 1)); + Assert.AreEqual(c.x12, (byte)realbinom((ushort)n.x12, k.x12)); + Assert.AreEqual(c.x13, (byte)realbinom((ushort)n.x13, 1)); + Assert.AreEqual(c.x14, (byte)realbinom((ushort)n.x14, k.x14)); + Assert.AreEqual(c.x15, (byte)realbinom((ushort)n.x15, 1)); + + c = maxmath.comb(n, new byte16(k.x0, 0, k.x2, 0, k.x4, 0, k.x6, 0, k.x8, 0, k.x10, 0, k.x12, 0, k.x14, 0)); + Assert.AreEqual(c.x0, (byte)realbinom((ushort)n.x0, k.x0)); + Assert.AreEqual(c.x1, (byte)realbinom((ushort)n.x1, 0)); + Assert.AreEqual(c.x2, (byte)realbinom((ushort)n.x2, k.x2)); + Assert.AreEqual(c.x3, (byte)realbinom((ushort)n.x3, 0)); + Assert.AreEqual(c.x4, (byte)realbinom((ushort)n.x4, k.x4)); + Assert.AreEqual(c.x5, (byte)realbinom((ushort)n.x5, 0)); + Assert.AreEqual(c.x6, (byte)realbinom((ushort)n.x6, k.x6)); + Assert.AreEqual(c.x7, (byte)realbinom((ushort)n.x7, 0)); + Assert.AreEqual(c.x8, (byte)realbinom((ushort)n.x8, k.x8)); + Assert.AreEqual(c.x9, (byte)realbinom((ushort)n.x9, 0)); + Assert.AreEqual(c.x10, (byte)realbinom((ushort)n.x10, k.x10)); + Assert.AreEqual(c.x11, (byte)realbinom((ushort)n.x11, 0)); + Assert.AreEqual(c.x12, (byte)realbinom((ushort)n.x12, k.x12)); + Assert.AreEqual(c.x13, (byte)realbinom((ushort)n.x13, 0)); + Assert.AreEqual(c.x14, (byte)realbinom((ushort)n.x14, k.x14)); + Assert.AreEqual(c.x15, (byte)realbinom((ushort)n.x15, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x0, (byte)realbinom((ushort)n.x0, 1)); + Assert.AreEqual(c.x1, (byte)realbinom((ushort)n.x1, 1)); + Assert.AreEqual(c.x2, (byte)realbinom((ushort)n.x2, 1)); + Assert.AreEqual(c.x3, (byte)realbinom((ushort)n.x3, 1)); + Assert.AreEqual(c.x4, (byte)realbinom((ushort)n.x4, 1)); + Assert.AreEqual(c.x5, (byte)realbinom((ushort)n.x5, 1)); + Assert.AreEqual(c.x6, (byte)realbinom((ushort)n.x6, 1)); + Assert.AreEqual(c.x7, (byte)realbinom((ushort)n.x7, 1)); + Assert.AreEqual(c.x8, (byte)realbinom((ushort)n.x8, 1)); + Assert.AreEqual(c.x9, (byte)realbinom((ushort)n.x9, 1)); + Assert.AreEqual(c.x10, (byte)realbinom((ushort)n.x10, 1)); + Assert.AreEqual(c.x11, (byte)realbinom((ushort)n.x11, 1)); + Assert.AreEqual(c.x12, (byte)realbinom((ushort)n.x12, 1)); + Assert.AreEqual(c.x13, (byte)realbinom((ushort)n.x13, 1)); + Assert.AreEqual(c.x14, (byte)realbinom((ushort)n.x14, 1)); + Assert.AreEqual(c.x15, (byte)realbinom((ushort)n.x15, 1)); + + c = maxmath.comb(new byte16(1), new byte16(0)); + Assert.AreEqual(c.x0, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x1, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x2, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x3, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x4, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x5, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x6, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x7, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x8, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x9, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x10, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x11, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x12, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x13, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x14, (byte)realbinom((ushort)1, 0)); + Assert.AreEqual(c.x15, (byte)realbinom((ushort)1, 0)); + + c = maxmath.comb(new byte16(1), new byte16(1)); + Assert.AreEqual(c.x0, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x1, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x2, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x3, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x4, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x5, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x6, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x7, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x8, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x9, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x10, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x11, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x12, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x13, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x14, (byte)realbinom((ushort)1, 1)); + Assert.AreEqual(c.x15, (byte)realbinom((ushort)1, 1)); + } + else + { + c = maxmath.comb(n, k); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, k.x1)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, k.x3)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, k.x5)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, k.x7)); + Assert.AreEqual(c.x8, realbinom(n.x8, k.x8)); + Assert.AreEqual(c.x9, realbinom(n.x9, k.x9)); + Assert.AreEqual(c.x10, realbinom(n.x10, k.x10)); + Assert.AreEqual(c.x11, realbinom(n.x11, k.x11)); + Assert.AreEqual(c.x12, realbinom(n.x12, k.x12)); + Assert.AreEqual(c.x13, realbinom(n.x13, k.x13)); + Assert.AreEqual(c.x14, realbinom(n.x14, k.x14)); + Assert.AreEqual(c.x15, realbinom(n.x15, k.x15)); + + c = maxmath.comb(n, k); + Assert.AreEqual(maxmath.comb(n, 0).x0, realbinom(n.x0, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x1, realbinom(n.x1, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x2, realbinom(n.x2, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x3, realbinom(n.x3, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x4, realbinom(n.x4, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x5, realbinom(n.x5, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x6, realbinom(n.x6, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x7, realbinom(n.x7, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x8, realbinom(n.x8, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x9, realbinom(n.x9, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x10, realbinom(n.x10, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x11, realbinom(n.x11, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x12, realbinom(n.x12, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x13, realbinom(n.x13, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x14, realbinom(n.x14, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x15, realbinom(n.x15, 0)); + + c = maxmath.comb(n, new byte16(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)); + Assert.AreEqual(c.x0, realbinom(n.x0, 0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, 0)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, 0)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, 0)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + Assert.AreEqual(c.x8, realbinom(n.x8, 0)); + Assert.AreEqual(c.x9, realbinom(n.x9, 1)); + Assert.AreEqual(c.x10, realbinom(n.x10, 0)); + Assert.AreEqual(c.x11, realbinom(n.x11, 1)); + Assert.AreEqual(c.x12, realbinom(n.x12, 0)); + Assert.AreEqual(c.x13, realbinom(n.x13, 1)); + Assert.AreEqual(c.x14, realbinom(n.x14, 0)); + Assert.AreEqual(c.x15, realbinom(n.x15, 1)); + + c = maxmath.comb(n, new byte16(k.x0, 1, k.x2, 1, k.x4, 1, k.x6, 1, k.x8, 1, k.x10, 1, k.x12, 1, k.x14, 1)); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + Assert.AreEqual(c.x8, realbinom(n.x8, k.x8)); + Assert.AreEqual(c.x9, realbinom(n.x9, 1)); + Assert.AreEqual(c.x10, realbinom(n.x10, k.x10)); + Assert.AreEqual(c.x11, realbinom(n.x11, 1)); + Assert.AreEqual(c.x12, realbinom(n.x12, k.x12)); + Assert.AreEqual(c.x13, realbinom(n.x13, 1)); + Assert.AreEqual(c.x14, realbinom(n.x14, k.x14)); + Assert.AreEqual(c.x15, realbinom(n.x15, 1)); + + c = maxmath.comb(n, new byte16(k.x0, 0, k.x2, 0, k.x4, 0, k.x6, 0, k.x8, 0, k.x10, 0, k.x12, 0, k.x14, 0)); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 0)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, 0)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, 0)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, 0)); + Assert.AreEqual(c.x8, realbinom(n.x8, k.x8)); + Assert.AreEqual(c.x9, realbinom(n.x9, 0)); + Assert.AreEqual(c.x10, realbinom(n.x10, k.x10)); + Assert.AreEqual(c.x11, realbinom(n.x11, 0)); + Assert.AreEqual(c.x12, realbinom(n.x12, k.x12)); + Assert.AreEqual(c.x13, realbinom(n.x13, 0)); + Assert.AreEqual(c.x14, realbinom(n.x14, k.x14)); + Assert.AreEqual(c.x15, realbinom(n.x15, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x0, realbinom(n.x0, 1)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, 1)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, 1)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, 1)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + Assert.AreEqual(c.x8, realbinom(n.x8, 1)); + Assert.AreEqual(c.x9, realbinom(n.x9, 1)); + Assert.AreEqual(c.x10, realbinom(n.x10, 1)); + Assert.AreEqual(c.x11, realbinom(n.x11, 1)); + Assert.AreEqual(c.x12, realbinom(n.x12, 1)); + Assert.AreEqual(c.x13, realbinom(n.x13, 1)); + Assert.AreEqual(c.x14, realbinom(n.x14, 1)); + Assert.AreEqual(c.x15, realbinom(n.x15, 1)); + + c = maxmath.comb(new byte16(1), new byte16(0)); + Assert.AreEqual(c.x0, realbinom(1, 0)); + Assert.AreEqual(c.x1, realbinom(1, 0)); + Assert.AreEqual(c.x2, realbinom(1, 0)); + Assert.AreEqual(c.x3, realbinom(1, 0)); + Assert.AreEqual(c.x4, realbinom(1, 0)); + Assert.AreEqual(c.x5, realbinom(1, 0)); + Assert.AreEqual(c.x6, realbinom(1, 0)); + Assert.AreEqual(c.x7, realbinom(1, 0)); + Assert.AreEqual(c.x8, realbinom(1, 0)); + Assert.AreEqual(c.x9, realbinom(1, 0)); + Assert.AreEqual(c.x10, realbinom(1, 0)); + Assert.AreEqual(c.x11, realbinom(1, 0)); + Assert.AreEqual(c.x12, realbinom(1, 0)); + Assert.AreEqual(c.x13, realbinom(1, 0)); + Assert.AreEqual(c.x14, realbinom(1, 0)); + Assert.AreEqual(c.x15, realbinom(1, 0)); + + c = maxmath.comb(new byte16(1), new byte16(1)); + Assert.AreEqual(c.x0, realbinom(1, 1)); + Assert.AreEqual(c.x1, realbinom(1, 1)); + Assert.AreEqual(c.x2, realbinom(1, 1)); + Assert.AreEqual(c.x3, realbinom(1, 1)); + Assert.AreEqual(c.x4, realbinom(1, 1)); + Assert.AreEqual(c.x5, realbinom(1, 1)); + Assert.AreEqual(c.x6, realbinom(1, 1)); + Assert.AreEqual(c.x7, realbinom(1, 1)); + Assert.AreEqual(c.x8, realbinom(1, 1)); + Assert.AreEqual(c.x9, realbinom(1, 1)); + Assert.AreEqual(c.x10, realbinom(1, 1)); + Assert.AreEqual(c.x11, realbinom(1, 1)); + Assert.AreEqual(c.x12, realbinom(1, 1)); + Assert.AreEqual(c.x13, realbinom(1, 1)); + Assert.AreEqual(c.x14, realbinom(1, 1)); + Assert.AreEqual(c.x15, realbinom(1, 1)); + } + } + } + + [Test] + public static void _byte32() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 8; i++) + { + byte32 n = rng.NextByte32(1, 64); + byte32 k = n - 1; + byte32 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x0, n.x0); + Assert.AreEqual(c.x1, n.x1); + Assert.AreEqual(c.x2, n.x2); + Assert.AreEqual(c.x3, n.x3); + Assert.AreEqual(c.x4, n.x4); + Assert.AreEqual(c.x5, n.x5); + Assert.AreEqual(c.x6, n.x6); + Assert.AreEqual(c.x7, n.x7); + Assert.AreEqual(c.x8, n.x8); + Assert.AreEqual(c.x9, n.x9); + Assert.AreEqual(c.x10, n.x10); + Assert.AreEqual(c.x11, n.x11); + Assert.AreEqual(c.x12, n.x12); + Assert.AreEqual(c.x13, n.x13); + Assert.AreEqual(c.x14, n.x14); + Assert.AreEqual(c.x15, n.x15); + Assert.AreEqual(c.x16, n.x16); + Assert.AreEqual(c.x17, n.x17); + Assert.AreEqual(c.x18, n.x18); + Assert.AreEqual(c.x19, n.x19); + Assert.AreEqual(c.x20, n.x20); + Assert.AreEqual(c.x21, n.x21); + Assert.AreEqual(c.x22, n.x22); + Assert.AreEqual(c.x23, n.x23); + Assert.AreEqual(c.x24, n.x24); + Assert.AreEqual(c.x25, n.x25); + Assert.AreEqual(c.x26, n.x26); + Assert.AreEqual(c.x27, n.x27); + Assert.AreEqual(c.x28, n.x28); + Assert.AreEqual(c.x29, n.x29); + Assert.AreEqual(c.x30, n.x30); + Assert.AreEqual(c.x31, n.x31); + + n = rng.NextByte32(1, byte.MaxValue); + k = rng.NextByte32(0, maxmath.min(rng.NextByte32(1, byte.MaxValue), maxmath.subsaturated(n, 25))); + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, k.x1)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, k.x3)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, k.x5)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, k.x7)); + Assert.AreEqual(c.x8, realbinom(n.x8, k.x8)); + Assert.AreEqual(c.x9, realbinom(n.x9, k.x9)); + Assert.AreEqual(c.x10, realbinom(n.x10, k.x10)); + Assert.AreEqual(c.x11, realbinom(n.x11, k.x11)); + Assert.AreEqual(c.x12, realbinom(n.x12, k.x12)); + Assert.AreEqual(c.x13, realbinom(n.x13, k.x13)); + Assert.AreEqual(c.x14, realbinom(n.x14, k.x14)); + Assert.AreEqual(c.x15, realbinom(n.x15, k.x15)); + Assert.AreEqual(c.x16, realbinom(n.x16, k.x16)); + Assert.AreEqual(c.x17, realbinom(n.x17, k.x17)); + Assert.AreEqual(c.x18, realbinom(n.x18, k.x18)); + Assert.AreEqual(c.x19, realbinom(n.x19, k.x19)); + Assert.AreEqual(c.x20, realbinom(n.x20, k.x20)); + Assert.AreEqual(c.x21, realbinom(n.x21, k.x21)); + Assert.AreEqual(c.x22, realbinom(n.x22, k.x22)); + Assert.AreEqual(c.x23, realbinom(n.x23, k.x23)); + Assert.AreEqual(c.x24, realbinom(n.x24, k.x24)); + Assert.AreEqual(c.x25, realbinom(n.x25, k.x25)); + Assert.AreEqual(c.x26, realbinom(n.x26, k.x26)); + Assert.AreEqual(c.x27, realbinom(n.x27, k.x27)); + Assert.AreEqual(c.x28, realbinom(n.x28, k.x28)); + Assert.AreEqual(c.x29, realbinom(n.x29, k.x29)); + Assert.AreEqual(c.x30, realbinom(n.x30, k.x30)); + Assert.AreEqual(c.x31, realbinom(n.x31, k.x31)); + + c = maxmath.comb(n, k); + Assert.AreEqual(maxmath.comb(n, 0).x0, realbinom(n.x0, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x1, realbinom(n.x1, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x2, realbinom(n.x2, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x3, realbinom(n.x3, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x4, realbinom(n.x4, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x5, realbinom(n.x5, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x6, realbinom(n.x6, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x7, realbinom(n.x7, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x8, realbinom(n.x8, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x9, realbinom(n.x9, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x10, realbinom(n.x10, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x11, realbinom(n.x11, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x12, realbinom(n.x12, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x13, realbinom(n.x13, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x14, realbinom(n.x14, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x15, realbinom(n.x15, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x16, realbinom(n.x16, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x17, realbinom(n.x17, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x18, realbinom(n.x18, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x19, realbinom(n.x19, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x20, realbinom(n.x20, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x21, realbinom(n.x21, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x22, realbinom(n.x22, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x23, realbinom(n.x23, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x24, realbinom(n.x24, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x25, realbinom(n.x25, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x26, realbinom(n.x26, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x27, realbinom(n.x27, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x28, realbinom(n.x28, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x29, realbinom(n.x29, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x30, realbinom(n.x30, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x31, realbinom(n.x31, 0)); + + c = maxmath.comb(n, new byte32(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)); + Assert.AreEqual(c.x0, realbinom(n.x0, 0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, 0)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, 0)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, 0)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + Assert.AreEqual(c.x8, realbinom(n.x8, 0)); + Assert.AreEqual(c.x9, realbinom(n.x9, 1)); + Assert.AreEqual(c.x10, realbinom(n.x10, 0)); + Assert.AreEqual(c.x11, realbinom(n.x11, 1)); + Assert.AreEqual(c.x12, realbinom(n.x12, 0)); + Assert.AreEqual(c.x13, realbinom(n.x13, 1)); + Assert.AreEqual(c.x14, realbinom(n.x14, 0)); + Assert.AreEqual(c.x15, realbinom(n.x15, 1)); + Assert.AreEqual(c.x16, realbinom(n.x16, 0)); + Assert.AreEqual(c.x17, realbinom(n.x17, 1)); + Assert.AreEqual(c.x18, realbinom(n.x18, 0)); + Assert.AreEqual(c.x19, realbinom(n.x19, 1)); + Assert.AreEqual(c.x20, realbinom(n.x20, 0)); + Assert.AreEqual(c.x21, realbinom(n.x21, 1)); + Assert.AreEqual(c.x22, realbinom(n.x22, 0)); + Assert.AreEqual(c.x23, realbinom(n.x23, 1)); + Assert.AreEqual(c.x24, realbinom(n.x24, 0)); + Assert.AreEqual(c.x25, realbinom(n.x25, 1)); + Assert.AreEqual(c.x26, realbinom(n.x26, 0)); + Assert.AreEqual(c.x27, realbinom(n.x27, 1)); + Assert.AreEqual(c.x28, realbinom(n.x28, 0)); + Assert.AreEqual(c.x29, realbinom(n.x29, 1)); + Assert.AreEqual(c.x30, realbinom(n.x30, 0)); + Assert.AreEqual(c.x31, realbinom(n.x31, 1)); + + c = maxmath.comb(n, new byte32(k.x0, 1, k.x2, 1, k.x4, 1, k.x6, 1, k.x8, 1, k.x10, 1, k.x12, 1, k.x14, 1, k.x16, 1, k.x18, 1, k.x20, 1, k.x22, 1, k.x24, 1, k.x26, 1, k.x28, 1, k.x30, 1)); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + Assert.AreEqual(c.x8, realbinom(n.x8, k.x8)); + Assert.AreEqual(c.x9, realbinom(n.x9, 1)); + Assert.AreEqual(c.x10, realbinom(n.x10, k.x10)); + Assert.AreEqual(c.x11, realbinom(n.x11, 1)); + Assert.AreEqual(c.x12, realbinom(n.x12, k.x12)); + Assert.AreEqual(c.x13, realbinom(n.x13, 1)); + Assert.AreEqual(c.x14, realbinom(n.x14, k.x14)); + Assert.AreEqual(c.x15, realbinom(n.x15, 1)); + Assert.AreEqual(c.x16, realbinom(n.x16, k.x16)); + Assert.AreEqual(c.x17, realbinom(n.x17, 1)); + Assert.AreEqual(c.x18, realbinom(n.x18, k.x18)); + Assert.AreEqual(c.x19, realbinom(n.x19, 1)); + Assert.AreEqual(c.x20, realbinom(n.x20, k.x20)); + Assert.AreEqual(c.x21, realbinom(n.x21, 1)); + Assert.AreEqual(c.x22, realbinom(n.x22, k.x22)); + Assert.AreEqual(c.x23, realbinom(n.x23, 1)); + Assert.AreEqual(c.x24, realbinom(n.x24, k.x24)); + Assert.AreEqual(c.x25, realbinom(n.x25, 1)); + Assert.AreEqual(c.x26, realbinom(n.x26, k.x26)); + Assert.AreEqual(c.x27, realbinom(n.x27, 1)); + Assert.AreEqual(c.x28, realbinom(n.x28, k.x28)); + Assert.AreEqual(c.x29, realbinom(n.x29, 1)); + Assert.AreEqual(c.x30, realbinom(n.x30, k.x30)); + Assert.AreEqual(c.x31, realbinom(n.x31, 1)); + + c = maxmath.comb(n, new byte32(k.x0, 0, k.x2, 0, k.x4, 0, k.x6, 0, k.x8, 0, k.x10, 0, k.x12, 0, k.x14, 0, k.x16, 0, k.x18, 0, k.x20, 0, k.x22, 0, k.x24, 0, k.x26, 0, k.x28, 0, k.x30, 0)); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 0)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, 0)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, 0)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, 0)); + Assert.AreEqual(c.x8, realbinom(n.x8, k.x8)); + Assert.AreEqual(c.x9, realbinom(n.x9, 0)); + Assert.AreEqual(c.x10, realbinom(n.x10, k.x10)); + Assert.AreEqual(c.x11, realbinom(n.x11, 0)); + Assert.AreEqual(c.x12, realbinom(n.x12, k.x12)); + Assert.AreEqual(c.x13, realbinom(n.x13, 0)); + Assert.AreEqual(c.x14, realbinom(n.x14, k.x14)); + Assert.AreEqual(c.x15, realbinom(n.x15, 0)); + Assert.AreEqual(c.x16, realbinom(n.x16, k.x16)); + Assert.AreEqual(c.x17, realbinom(n.x17, 0)); + Assert.AreEqual(c.x18, realbinom(n.x18, k.x18)); + Assert.AreEqual(c.x19, realbinom(n.x19, 0)); + Assert.AreEqual(c.x20, realbinom(n.x20, k.x20)); + Assert.AreEqual(c.x21, realbinom(n.x21, 0)); + Assert.AreEqual(c.x22, realbinom(n.x22, k.x22)); + Assert.AreEqual(c.x23, realbinom(n.x23, 0)); + Assert.AreEqual(c.x24, realbinom(n.x24, k.x24)); + Assert.AreEqual(c.x25, realbinom(n.x25, 0)); + Assert.AreEqual(c.x26, realbinom(n.x26, k.x26)); + Assert.AreEqual(c.x27, realbinom(n.x27, 0)); + Assert.AreEqual(c.x28, realbinom(n.x28, k.x28)); + Assert.AreEqual(c.x29, realbinom(n.x29, 0)); + Assert.AreEqual(c.x30, realbinom(n.x30, k.x30)); + Assert.AreEqual(c.x31, realbinom(n.x31, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x0, realbinom(n.x0, 1)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, 1)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, 1)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, 1)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + Assert.AreEqual(c.x8, realbinom(n.x8, 1)); + Assert.AreEqual(c.x9, realbinom(n.x9, 1)); + Assert.AreEqual(c.x10, realbinom(n.x10, 1)); + Assert.AreEqual(c.x11, realbinom(n.x11, 1)); + Assert.AreEqual(c.x12, realbinom(n.x12, 1)); + Assert.AreEqual(c.x13, realbinom(n.x13, 1)); + Assert.AreEqual(c.x14, realbinom(n.x14, 1)); + Assert.AreEqual(c.x15, realbinom(n.x15, 1)); + Assert.AreEqual(c.x16, realbinom(n.x16, 1)); + Assert.AreEqual(c.x17, realbinom(n.x17, 1)); + Assert.AreEqual(c.x18, realbinom(n.x18, 1)); + Assert.AreEqual(c.x19, realbinom(n.x19, 1)); + Assert.AreEqual(c.x20, realbinom(n.x20, 1)); + Assert.AreEqual(c.x21, realbinom(n.x21, 1)); + Assert.AreEqual(c.x22, realbinom(n.x22, 1)); + Assert.AreEqual(c.x23, realbinom(n.x23, 1)); + Assert.AreEqual(c.x24, realbinom(n.x24, 1)); + Assert.AreEqual(c.x25, realbinom(n.x25, 1)); + Assert.AreEqual(c.x26, realbinom(n.x26, 1)); + Assert.AreEqual(c.x27, realbinom(n.x27, 1)); + Assert.AreEqual(c.x28, realbinom(n.x28, 1)); + Assert.AreEqual(c.x29, realbinom(n.x29, 1)); + Assert.AreEqual(c.x30, realbinom(n.x30, 1)); + Assert.AreEqual(c.x31, realbinom(n.x31, 1)); + + c = maxmath.comb(new byte32(1), new byte32(0)); + Assert.AreEqual(c.x0, realbinom(1, 0)); + Assert.AreEqual(c.x1, realbinom(1, 0)); + Assert.AreEqual(c.x2, realbinom(1, 0)); + Assert.AreEqual(c.x3, realbinom(1, 0)); + Assert.AreEqual(c.x4, realbinom(1, 0)); + Assert.AreEqual(c.x5, realbinom(1, 0)); + Assert.AreEqual(c.x6, realbinom(1, 0)); + Assert.AreEqual(c.x7, realbinom(1, 0)); + Assert.AreEqual(c.x8, realbinom(1, 0)); + Assert.AreEqual(c.x9, realbinom(1, 0)); + Assert.AreEqual(c.x10, realbinom(1, 0)); + Assert.AreEqual(c.x11, realbinom(1, 0)); + Assert.AreEqual(c.x12, realbinom(1, 0)); + Assert.AreEqual(c.x13, realbinom(1, 0)); + Assert.AreEqual(c.x14, realbinom(1, 0)); + Assert.AreEqual(c.x15, realbinom(1, 0)); + Assert.AreEqual(c.x16, realbinom(1, 0)); + Assert.AreEqual(c.x17, realbinom(1, 0)); + Assert.AreEqual(c.x18, realbinom(1, 0)); + Assert.AreEqual(c.x19, realbinom(1, 0)); + Assert.AreEqual(c.x20, realbinom(1, 0)); + Assert.AreEqual(c.x21, realbinom(1, 0)); + Assert.AreEqual(c.x22, realbinom(1, 0)); + Assert.AreEqual(c.x23, realbinom(1, 0)); + Assert.AreEqual(c.x24, realbinom(1, 0)); + Assert.AreEqual(c.x25, realbinom(1, 0)); + Assert.AreEqual(c.x26, realbinom(1, 0)); + Assert.AreEqual(c.x27, realbinom(1, 0)); + Assert.AreEqual(c.x28, realbinom(1, 0)); + Assert.AreEqual(c.x29, realbinom(1, 0)); + Assert.AreEqual(c.x30, realbinom(1, 0)); + Assert.AreEqual(c.x31, realbinom(1, 0)); + + c = maxmath.comb(new byte32(1), new byte32(1)); + Assert.AreEqual(c.x0, realbinom(1, 1)); + Assert.AreEqual(c.x1, realbinom(1, 1)); + Assert.AreEqual(c.x2, realbinom(1, 1)); + Assert.AreEqual(c.x3, realbinom(1, 1)); + Assert.AreEqual(c.x4, realbinom(1, 1)); + Assert.AreEqual(c.x5, realbinom(1, 1)); + Assert.AreEqual(c.x6, realbinom(1, 1)); + Assert.AreEqual(c.x7, realbinom(1, 1)); + Assert.AreEqual(c.x8, realbinom(1, 1)); + Assert.AreEqual(c.x9, realbinom(1, 1)); + Assert.AreEqual(c.x10, realbinom(1, 1)); + Assert.AreEqual(c.x11, realbinom(1, 1)); + Assert.AreEqual(c.x12, realbinom(1, 1)); + Assert.AreEqual(c.x13, realbinom(1, 1)); + Assert.AreEqual(c.x14, realbinom(1, 1)); + Assert.AreEqual(c.x15, realbinom(1, 1)); + Assert.AreEqual(c.x16, realbinom(1, 1)); + Assert.AreEqual(c.x17, realbinom(1, 1)); + Assert.AreEqual(c.x18, realbinom(1, 1)); + Assert.AreEqual(c.x19, realbinom(1, 1)); + Assert.AreEqual(c.x20, realbinom(1, 1)); + Assert.AreEqual(c.x21, realbinom(1, 1)); + Assert.AreEqual(c.x22, realbinom(1, 1)); + Assert.AreEqual(c.x23, realbinom(1, 1)); + Assert.AreEqual(c.x24, realbinom(1, 1)); + Assert.AreEqual(c.x25, realbinom(1, 1)); + Assert.AreEqual(c.x26, realbinom(1, 1)); + Assert.AreEqual(c.x27, realbinom(1, 1)); + Assert.AreEqual(c.x28, realbinom(1, 1)); + Assert.AreEqual(c.x29, realbinom(1, 1)); + Assert.AreEqual(c.x30, realbinom(1, 1)); + Assert.AreEqual(c.x31, realbinom(1, 1)); + } + } + + + [Test] + public static void _ushort2() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 18; i++) + { + ushort2 n = rng.NextUShort2(1, 128); + ushort2 k = n - 1; + ushort2 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, n.x); + Assert.AreEqual(c.y, n.y); + + n = rng.NextUShort2(1, ushort.MaxValue); + k = rng.NextUShort2(0, n + 1); + k = maxmath.select(k, n - 1000, n - k > 1000); + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, k.y)); + + c = maxmath.comb(n, 0); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + + c = maxmath.comb(n, new ushort2(0, 1)); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + + c = maxmath.comb(n, new ushort2(k.x, 1)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + + c = maxmath.comb(n, new ushort2(k.x, 0)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x, realbinom(n.x, 1)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + + c = maxmath.comb(new ushort2(1), new ushort2(0)); + Assert.AreEqual(c.x, realbinom(1, 0)); + Assert.AreEqual(c.y, realbinom(1, 0)); + + c = maxmath.comb(new ushort2(1), new ushort2(1)); + Assert.AreEqual(c.x, realbinom(1, 1)); + Assert.AreEqual(c.y, realbinom(1, 1)); + } + } + + [Test] + public static void _ushort3() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 16; i++) + { + ushort3 n = rng.NextUShort3(1, 128); + ushort3 k = n - 1; + ushort3 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, n.x); + Assert.AreEqual(c.y, n.y); + Assert.AreEqual(c.z, n.z); + + n = rng.NextUShort3(1, ushort.MaxValue); + k = rng.NextUShort3(0, n + 1); + k = maxmath.select(k, n - 1000, n - k > 1000); + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, k.y)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + + c = maxmath.comb(n, 0); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + Assert.AreEqual(c.z, realbinom(n.z, 0)); + + c = maxmath.comb(n, new ushort3(0, 1, 0)); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 0)); + + c = maxmath.comb(n, new ushort3(k.x, 1, k.z)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + + c = maxmath.comb(n, new ushort3(k.x, 0, k.z)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x, realbinom(n.x, 1)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 1)); + + c = maxmath.comb(new ushort3(1), new ushort3(0)); + Assert.AreEqual(c.x, realbinom(1, 0)); + Assert.AreEqual(c.y, realbinom(1, 0)); + Assert.AreEqual(c.z, realbinom(1, 0)); + + c = maxmath.comb(new ushort3(1), new ushort3(1)); + Assert.AreEqual(c.x, realbinom(1, 1)); + Assert.AreEqual(c.y, realbinom(1, 1)); + Assert.AreEqual(c.z, realbinom(1, 1)); + } + } + + [Test] + public static void _ushort4() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 14; i++) + { + ushort4 n = rng.NextUShort4(1, 128); + ushort4 k = n - 1; + ushort4 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, n.x); + Assert.AreEqual(c.y, n.y); + Assert.AreEqual(c.z, n.z); + Assert.AreEqual(c.w, n.w); + + n = rng.NextUShort4(1, ushort.MaxValue); + k = rng.NextUShort4(0, n + 1); + k = maxmath.select(k, n - 1000, n - k > 1000); + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, k.y)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + Assert.AreEqual(c.w, realbinom(n.w, k.w)); + + c = maxmath.comb(n, k); + Assert.AreEqual(maxmath.comb(n, 0).x, realbinom(n.x, 0)); + Assert.AreEqual(maxmath.comb(n, 0).y, realbinom(n.y, 0)); + Assert.AreEqual(maxmath.comb(n, 0).z, realbinom(n.z, 0)); + Assert.AreEqual(maxmath.comb(n, 0).w, realbinom(n.w, 0)); + + c = maxmath.comb(n, new ushort4(0, 1, 0, 1)); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 0)); + Assert.AreEqual(c.w, realbinom(n.w, 1)); + + c = maxmath.comb(n, new ushort4(k.x, 1, k.z, 1)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + Assert.AreEqual(c.w, realbinom(n.w, 1)); + + c = maxmath.comb(n, new ushort4(k.x, 0, k.z, 0)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + Assert.AreEqual(c.w, realbinom(n.w, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x, realbinom(n.x, 1)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 1)); + Assert.AreEqual(c.w, realbinom(n.w, 1)); + + c = maxmath.comb(new ushort4(1), new ushort4(0)); + Assert.AreEqual(c.x, realbinom(1, 0)); + Assert.AreEqual(c.y, realbinom(1, 0)); + Assert.AreEqual(c.z, realbinom(1, 0)); + Assert.AreEqual(c.w, realbinom(1, 0)); + + c = maxmath.comb(new ushort4(1), new ushort4(1)); + Assert.AreEqual(c.x, realbinom(1, 1)); + Assert.AreEqual(c.y, realbinom(1, 1)); + Assert.AreEqual(c.z, realbinom(1, 1)); + Assert.AreEqual(c.w, realbinom(1, 1)); + } + } + + [Test] + public static void _ushort8() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 12; i++) + { + ushort8 n = rng.NextUShort8(1, 128); + ushort8 k = n - 1; + ushort8 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x0, n.x0); + Assert.AreEqual(c.x1, n.x1); + Assert.AreEqual(c.x2, n.x2); + Assert.AreEqual(c.x3, n.x3); + Assert.AreEqual(c.x4, n.x4); + Assert.AreEqual(c.x5, n.x5); + Assert.AreEqual(c.x6, n.x6); + Assert.AreEqual(c.x7, n.x7); + + n = rng.NextUShort8(1, ushort.MaxValue); + k = rng.NextUShort8(0, n + 1); + k = maxmath.select(k, n - 1000, n - k > 1000); + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, k.x1)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, k.x3)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, k.x5)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, k.x7)); + + c = maxmath.comb(n, k); + Assert.AreEqual(maxmath.comb(n, 0).x0, realbinom(n.x0, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x1, realbinom(n.x1, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x2, realbinom(n.x2, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x3, realbinom(n.x3, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x4, realbinom(n.x4, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x5, realbinom(n.x5, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x6, realbinom(n.x6, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x7, realbinom(n.x7, 0)); + + c = maxmath.comb(n, new ushort8(0, 1, 0, 1, 0, 1, 0, 1)); + Assert.AreEqual(c.x0, realbinom(n.x0, 0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, 0)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, 0)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, 0)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + + c = maxmath.comb(n, new ushort8(k.x0, 1, k.x2, 1, k.x4, 1, k.x6, 1)); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + + c = maxmath.comb(n, new ushort8(k.x0, 0, k.x2, 0, k.x4, 0, k.x6, 0)); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 0)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, 0)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, 0)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x0, realbinom(n.x0, 1)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, 1)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, 1)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, 1)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + + c = maxmath.comb(new ushort8(1), new ushort8(0)); + Assert.AreEqual(c.x0, realbinom(1, 0)); + Assert.AreEqual(c.x1, realbinom(1, 0)); + Assert.AreEqual(c.x2, realbinom(1, 0)); + Assert.AreEqual(c.x3, realbinom(1, 0)); + Assert.AreEqual(c.x4, realbinom(1, 0)); + Assert.AreEqual(c.x5, realbinom(1, 0)); + Assert.AreEqual(c.x6, realbinom(1, 0)); + Assert.AreEqual(c.x7, realbinom(1, 0)); + + c = maxmath.comb(new ushort8(1), new ushort8(1)); + Assert.AreEqual(c.x0, realbinom(1, 1)); + Assert.AreEqual(c.x1, realbinom(1, 1)); + Assert.AreEqual(c.x2, realbinom(1, 1)); + Assert.AreEqual(c.x3, realbinom(1, 1)); + Assert.AreEqual(c.x4, realbinom(1, 1)); + Assert.AreEqual(c.x5, realbinom(1, 1)); + Assert.AreEqual(c.x6, realbinom(1, 1)); + Assert.AreEqual(c.x7, realbinom(1, 1)); + } + } + + [Test] + public static void _ushort16() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 10; i++) + { + ushort16 n = rng.NextUShort16(1, 128); + ushort16 k = n - 1; + ushort16 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x0, n.x0); + Assert.AreEqual(c.x1, n.x1); + Assert.AreEqual(c.x2, n.x2); + Assert.AreEqual(c.x3, n.x3); + Assert.AreEqual(c.x4, n.x4); + Assert.AreEqual(c.x5, n.x5); + Assert.AreEqual(c.x6, n.x6); + Assert.AreEqual(c.x7, n.x7); + Assert.AreEqual(c.x8, n.x8); + Assert.AreEqual(c.x9, n.x9); + Assert.AreEqual(c.x10, n.x10); + Assert.AreEqual(c.x11, n.x11); + Assert.AreEqual(c.x12, n.x12); + Assert.AreEqual(c.x13, n.x13); + Assert.AreEqual(c.x14, n.x14); + Assert.AreEqual(c.x15, n.x15); + + n = rng.NextUShort16(1, ushort.MaxValue); + k = rng.NextUShort16(0, n + 1); + k = maxmath.select(k, n - 1000, n - k > 1000); + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, k.x1)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, k.x3)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, k.x5)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, k.x7)); + Assert.AreEqual(c.x8, realbinom(n.x8, k.x8)); + Assert.AreEqual(c.x9, realbinom(n.x9, k.x9)); + Assert.AreEqual(c.x10, realbinom(n.x10, k.x10)); + Assert.AreEqual(c.x11, realbinom(n.x11, k.x11)); + Assert.AreEqual(c.x12, realbinom(n.x12, k.x12)); + Assert.AreEqual(c.x13, realbinom(n.x13, k.x13)); + Assert.AreEqual(c.x14, realbinom(n.x14, k.x14)); + Assert.AreEqual(c.x15, realbinom(n.x15, k.x15)); + + c = maxmath.comb(n, k); + Assert.AreEqual(maxmath.comb(n, 0).x0, realbinom(n.x0, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x1, realbinom(n.x1, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x2, realbinom(n.x2, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x3, realbinom(n.x3, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x4, realbinom(n.x4, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x5, realbinom(n.x5, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x6, realbinom(n.x6, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x7, realbinom(n.x7, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x8, realbinom(n.x8, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x9, realbinom(n.x9, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x10, realbinom(n.x10, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x11, realbinom(n.x11, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x12, realbinom(n.x12, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x13, realbinom(n.x13, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x14, realbinom(n.x14, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x15, realbinom(n.x15, 0)); + + c = maxmath.comb(n, new ushort16(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)); + Assert.AreEqual(c.x0, realbinom(n.x0, 0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, 0)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, 0)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, 0)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + Assert.AreEqual(c.x8, realbinom(n.x8, 0)); + Assert.AreEqual(c.x9, realbinom(n.x9, 1)); + Assert.AreEqual(c.x10, realbinom(n.x10, 0)); + Assert.AreEqual(c.x11, realbinom(n.x11, 1)); + Assert.AreEqual(c.x12, realbinom(n.x12, 0)); + Assert.AreEqual(c.x13, realbinom(n.x13, 1)); + Assert.AreEqual(c.x14, realbinom(n.x14, 0)); + Assert.AreEqual(c.x15, realbinom(n.x15, 1)); + + c = maxmath.comb(n, new ushort16(k.x0, 1, k.x2, 1, k.x4, 1, k.x6, 1, k.x8, 1, k.x10, 1, k.x12, 1, k.x14, 1)); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + Assert.AreEqual(c.x8, realbinom(n.x8, k.x8)); + Assert.AreEqual(c.x9, realbinom(n.x9, 1)); + Assert.AreEqual(c.x10, realbinom(n.x10, k.x10)); + Assert.AreEqual(c.x11, realbinom(n.x11, 1)); + Assert.AreEqual(c.x12, realbinom(n.x12, k.x12)); + Assert.AreEqual(c.x13, realbinom(n.x13, 1)); + Assert.AreEqual(c.x14, realbinom(n.x14, k.x14)); + Assert.AreEqual(c.x15, realbinom(n.x15, 1)); + + c = maxmath.comb(n, new ushort16(k.x0, 0, k.x2, 0, k.x4, 0, k.x6, 0, k.x8, 0, k.x10, 0, k.x12, 0, k.x14, 0)); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 0)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, 0)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, 0)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, 0)); + Assert.AreEqual(c.x8, realbinom(n.x8, k.x8)); + Assert.AreEqual(c.x9, realbinom(n.x9, 0)); + Assert.AreEqual(c.x10, realbinom(n.x10, k.x10)); + Assert.AreEqual(c.x11, realbinom(n.x11, 0)); + Assert.AreEqual(c.x12, realbinom(n.x12, k.x12)); + Assert.AreEqual(c.x13, realbinom(n.x13, 0)); + Assert.AreEqual(c.x14, realbinom(n.x14, k.x14)); + Assert.AreEqual(c.x15, realbinom(n.x15, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x0, realbinom(n.x0, 1)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, 1)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, 1)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, 1)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + Assert.AreEqual(c.x8, realbinom(n.x8, 1)); + Assert.AreEqual(c.x9, realbinom(n.x9, 1)); + Assert.AreEqual(c.x10, realbinom(n.x10, 1)); + Assert.AreEqual(c.x11, realbinom(n.x11, 1)); + Assert.AreEqual(c.x12, realbinom(n.x12, 1)); + Assert.AreEqual(c.x13, realbinom(n.x13, 1)); + Assert.AreEqual(c.x14, realbinom(n.x14, 1)); + Assert.AreEqual(c.x15, realbinom(n.x15, 1)); + + c = maxmath.comb(new ushort16(1), new ushort16(0)); + Assert.AreEqual(c.x0, realbinom(1, 0)); + Assert.AreEqual(c.x1, realbinom(1, 0)); + Assert.AreEqual(c.x2, realbinom(1, 0)); + Assert.AreEqual(c.x3, realbinom(1, 0)); + Assert.AreEqual(c.x4, realbinom(1, 0)); + Assert.AreEqual(c.x5, realbinom(1, 0)); + Assert.AreEqual(c.x6, realbinom(1, 0)); + Assert.AreEqual(c.x7, realbinom(1, 0)); + Assert.AreEqual(c.x8, realbinom(1, 0)); + Assert.AreEqual(c.x9, realbinom(1, 0)); + Assert.AreEqual(c.x10, realbinom(1, 0)); + Assert.AreEqual(c.x11, realbinom(1, 0)); + Assert.AreEqual(c.x12, realbinom(1, 0)); + Assert.AreEqual(c.x13, realbinom(1, 0)); + Assert.AreEqual(c.x14, realbinom(1, 0)); + Assert.AreEqual(c.x15, realbinom(1, 0)); + + c = maxmath.comb(new ushort16(1), new ushort16(1)); + Assert.AreEqual(c.x0, realbinom(1, 1)); + Assert.AreEqual(c.x1, realbinom(1, 1)); + Assert.AreEqual(c.x2, realbinom(1, 1)); + Assert.AreEqual(c.x3, realbinom(1, 1)); + Assert.AreEqual(c.x4, realbinom(1, 1)); + Assert.AreEqual(c.x5, realbinom(1, 1)); + Assert.AreEqual(c.x6, realbinom(1, 1)); + Assert.AreEqual(c.x7, realbinom(1, 1)); + Assert.AreEqual(c.x8, realbinom(1, 1)); + Assert.AreEqual(c.x9, realbinom(1, 1)); + Assert.AreEqual(c.x10, realbinom(1, 1)); + Assert.AreEqual(c.x11, realbinom(1, 1)); + Assert.AreEqual(c.x12, realbinom(1, 1)); + Assert.AreEqual(c.x13, realbinom(1, 1)); + Assert.AreEqual(c.x14, realbinom(1, 1)); + Assert.AreEqual(c.x15, realbinom(1, 1)); + } + } + + + [Test] + public static void _uint2() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 10; i++) + { + uint2 n = rng.NextUInt2(1, byte.MaxValue); + uint2 k = n - 1; + uint2 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, n.x); + Assert.AreEqual(c.y, n.y); + + n = rng.NextUInt2(1, uint.MaxValue); + k = rng.NextUInt2(0, n + 1); + k = math.select(k, n - 1000, n - k > 1000); + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, k.y)); + + c = maxmath.comb(n, 0); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + + c = maxmath.comb(n, new uint2(0, 1)); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + + c = maxmath.comb(n, new uint2(k.x, 1)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + + c = maxmath.comb(n, new uint2(k.x, 0)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x, realbinom(n.x, 1)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + + c = maxmath.comb(new uint2(1), new uint2(0)); + Assert.AreEqual(c.x, realbinom(1, 0)); + Assert.AreEqual(c.y, realbinom(1, 0)); + + c = maxmath.comb(new uint2(1), new uint2(1)); + Assert.AreEqual(c.x, realbinom(1, 1)); + Assert.AreEqual(c.y, realbinom(1, 1)); + } + } + + [Test] + public static void _uint3() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 8; i++) + { + uint3 n = rng.NextUInt3(1, byte.MaxValue); + uint3 k = n - 1; + uint3 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, n.x); + Assert.AreEqual(c.y, n.y); + Assert.AreEqual(c.z, n.z); + + n = rng.NextUInt3(1, uint.MaxValue); + k = rng.NextUInt3(0, n + 1); + k = math.select(k, n - 1000, n - k > 1000); + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, k.y)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + + c = maxmath.comb(n, 0); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + Assert.AreEqual(c.z, realbinom(n.z, 0)); + + c = maxmath.comb(n, new uint3(0, 1, 0)); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 0)); + + c = maxmath.comb(n, new uint3(k.x, 1, k.z)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + + c = maxmath.comb(n, new uint3(k.x, 0, k.z)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x, realbinom(n.x, 1)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 1)); + + c = maxmath.comb(new uint3(1), new uint3(0)); + Assert.AreEqual(c.x, realbinom(1, 0)); + Assert.AreEqual(c.y, realbinom(1, 0)); + Assert.AreEqual(c.z, realbinom(1, 0)); + + c = maxmath.comb(new uint3(1), new uint3(1)); + Assert.AreEqual(c.x, realbinom(1, 1)); + Assert.AreEqual(c.y, realbinom(1, 1)); + Assert.AreEqual(c.z, realbinom(1, 1)); + } + } + + [Test] + public static void _uint4() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 6; i++) + { + uint4 n = rng.NextUInt4(1, byte.MaxValue); + uint4 k = n - 1; + uint4 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, n.x); + Assert.AreEqual(c.y, n.y); + Assert.AreEqual(c.z, n.z); + Assert.AreEqual(c.w, n.w); + + n = rng.NextUInt4(1, uint.MaxValue); + k = rng.NextUInt4(0, n + 1); + k = math.select(k, n - 1000, n - k > 1000); + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, k.y)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + Assert.AreEqual(c.w, realbinom(n.w, k.w)); + + c = maxmath.comb(n, k); + Assert.AreEqual(maxmath.comb(n, 0).x, realbinom(n.x, 0)); + Assert.AreEqual(maxmath.comb(n, 0).y, realbinom(n.y, 0)); + Assert.AreEqual(maxmath.comb(n, 0).z, realbinom(n.z, 0)); + Assert.AreEqual(maxmath.comb(n, 0).w, realbinom(n.w, 0)); + + c = maxmath.comb(n, new uint4(0, 1, 0, 1)); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 0)); + Assert.AreEqual(c.w, realbinom(n.w, 1)); + + c = maxmath.comb(n, new uint4(k.x, 1, k.z, 1)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + Assert.AreEqual(c.w, realbinom(n.w, 1)); + + c = maxmath.comb(n, new uint4(k.x, 0, k.z, 0)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + Assert.AreEqual(c.w, realbinom(n.w, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x, realbinom(n.x, 1)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 1)); + Assert.AreEqual(c.w, realbinom(n.w, 1)); + + c = maxmath.comb(new uint4(1), new uint4(0)); + Assert.AreEqual(c.x, realbinom(1, 0)); + Assert.AreEqual(c.y, realbinom(1, 0)); + Assert.AreEqual(c.z, realbinom(1, 0)); + Assert.AreEqual(c.w, realbinom(1, 0)); + + c = maxmath.comb(new uint4(1), new uint4(1)); + Assert.AreEqual(c.x, realbinom(1, 1)); + Assert.AreEqual(c.y, realbinom(1, 1)); + Assert.AreEqual(c.z, realbinom(1, 1)); + Assert.AreEqual(c.w, realbinom(1, 1)); + } + } + + [Test] + public static void _uint8() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 4; i++) + { + uint8 n = rng.NextUInt8(1, byte.MaxValue); + uint8 k = n - 1; + uint8 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x0, n.x0); + Assert.AreEqual(c.x1, n.x1); + Assert.AreEqual(c.x2, n.x2); + Assert.AreEqual(c.x3, n.x3); + Assert.AreEqual(c.x4, n.x4); + Assert.AreEqual(c.x5, n.x5); + Assert.AreEqual(c.x6, n.x6); + Assert.AreEqual(c.x7, n.x7); + + n = rng.NextUInt8(1, uint.MaxValue); + k = rng.NextUInt8(0, n + 1); + k = maxmath.select(k, n - 1000, n - k > 1000); + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, k.x1)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, k.x3)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, k.x5)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, k.x7)); + + c = maxmath.comb(n, k); + Assert.AreEqual(maxmath.comb(n, 0).x0, realbinom(n.x0, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x1, realbinom(n.x1, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x2, realbinom(n.x2, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x3, realbinom(n.x3, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x4, realbinom(n.x4, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x5, realbinom(n.x5, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x6, realbinom(n.x6, 0)); + Assert.AreEqual(maxmath.comb(n, 0).x7, realbinom(n.x7, 0)); + + c = maxmath.comb(n, new uint8(0, 1, 0, 1, 0, 1, 0, 1)); + Assert.AreEqual(c.x0, realbinom(n.x0, 0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, 0)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, 0)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, 0)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + + c = maxmath.comb(n, new uint8(k.x0, 1, k.x2, 1, k.x4, 1, k.x6, 1)); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + + c = maxmath.comb(n, new uint8(k.x0, 0, k.x2, 0, k.x4, 0, k.x6, 0)); + Assert.AreEqual(c.x0, realbinom(n.x0, k.x0)); + Assert.AreEqual(c.x1, realbinom(n.x1, 0)); + Assert.AreEqual(c.x2, realbinom(n.x2, k.x2)); + Assert.AreEqual(c.x3, realbinom(n.x3, 0)); + Assert.AreEqual(c.x4, realbinom(n.x4, k.x4)); + Assert.AreEqual(c.x5, realbinom(n.x5, 0)); + Assert.AreEqual(c.x6, realbinom(n.x6, k.x6)); + Assert.AreEqual(c.x7, realbinom(n.x7, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x0, realbinom(n.x0, 1)); + Assert.AreEqual(c.x1, realbinom(n.x1, 1)); + Assert.AreEqual(c.x2, realbinom(n.x2, 1)); + Assert.AreEqual(c.x3, realbinom(n.x3, 1)); + Assert.AreEqual(c.x4, realbinom(n.x4, 1)); + Assert.AreEqual(c.x5, realbinom(n.x5, 1)); + Assert.AreEqual(c.x6, realbinom(n.x6, 1)); + Assert.AreEqual(c.x7, realbinom(n.x7, 1)); + + c = maxmath.comb(new uint8(1), new uint8(0)); + Assert.AreEqual(c.x0, realbinom(1, 0)); + Assert.AreEqual(c.x1, realbinom(1, 0)); + Assert.AreEqual(c.x2, realbinom(1, 0)); + Assert.AreEqual(c.x3, realbinom(1, 0)); + Assert.AreEqual(c.x4, realbinom(1, 0)); + Assert.AreEqual(c.x5, realbinom(1, 0)); + Assert.AreEqual(c.x6, realbinom(1, 0)); + Assert.AreEqual(c.x7, realbinom(1, 0)); + + c = maxmath.comb(new uint8(1), new uint8(1)); + Assert.AreEqual(c.x0, realbinom(1, 1)); + Assert.AreEqual(c.x1, realbinom(1, 1)); + Assert.AreEqual(c.x2, realbinom(1, 1)); + Assert.AreEqual(c.x3, realbinom(1, 1)); + Assert.AreEqual(c.x4, realbinom(1, 1)); + Assert.AreEqual(c.x5, realbinom(1, 1)); + Assert.AreEqual(c.x6, realbinom(1, 1)); + Assert.AreEqual(c.x7, realbinom(1, 1)); + } + } + + + [Test] + public static void _ulong() + { + Random64 rng = Random64.New; + + for (int i = 0; i < 10; i++) + { + ulong n = rng.NextULong(1, ulong.MaxValue); + ulong k = n - 1; + + Assert.AreEqual(maxmath.comb(n, k), n); + + n = rng.NextULong(1, ulong.MaxValue); + k = rng.NextULong(0, n + 1); + k = math.select(k, n - 1000, n - k > 1000); + + Assert.AreEqual(maxmath.comb((ulong)n, (ulong)k), realbinom((ulong)n, (ulong)k)); + Assert.AreEqual(maxmath.comb((ulong)n, (ulong)0), realbinom((ulong)n, (ulong)0)); + Assert.AreEqual(maxmath.comb((ulong)n, (ulong)1), realbinom((ulong)n, (ulong)1)); + Assert.AreEqual(maxmath.comb((ulong)1, (ulong)0), realbinom((ulong)1, (ulong)0)); + Assert.AreEqual(maxmath.comb((ulong)1, (ulong)1), realbinom((ulong)1, (ulong)1)); + } + } + + [Test] + public static void _ulong2() + { + Random64 rng = Random64.New; + + for (int i = 0; i < 8; i++) + { + ulong2 n = rng.NextULong2(1, ulong.MaxValue); + ulong2 k = n - 1; + ulong2 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, n.x); + Assert.AreEqual(c.y, n.y); + + n = rng.NextULong2(1, ulong.MaxValue); + k = rng.NextULong2(0, n + 1); + k = maxmath.select(k, n - 1000, n - k > 1000); + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, k.y)); + + c = maxmath.comb(n, 0); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + + c = maxmath.comb(n, new ulong2(0, 1)); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + + c = maxmath.comb(n, new ulong2(k.x, 1)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + + c = maxmath.comb(n, new ulong2(k.x, 0)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x, realbinom(n.x, 1)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + + c = maxmath.comb(new ulong2(1), new ulong2(0)); + Assert.AreEqual(c.x, realbinom(1, 0)); + Assert.AreEqual(c.y, realbinom(1, 0)); + + c = maxmath.comb(new ulong2(1), new ulong2(1)); + Assert.AreEqual(c.x, realbinom(1, 1)); + Assert.AreEqual(c.y, realbinom(1, 1)); + } + } + + [Test] + public static void _ulong3() + { + Random64 rng = Random64.New; + + for (int i = 0; i < 6; i++) + { + ulong3 n = rng.NextULong3(1, ulong.MaxValue); + ulong3 k = n - 1; + ulong3 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, n.x); + Assert.AreEqual(c.y, n.y); + Assert.AreEqual(c.z, n.z); + + n = rng.NextULong3(1, ulong.MaxValue); + k = rng.NextULong3(0, n + 1); + k = maxmath.select(k, n - 1000, n - k > 1000); + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, k.y)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + + c = maxmath.comb(n, 0); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + Assert.AreEqual(c.z, realbinom(n.z, 0)); + + c = maxmath.comb(n, new ulong3(0, 1, 0)); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 0)); + + c = maxmath.comb(n, new ulong3(k.x, 1, 0)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 0)); + + c = maxmath.comb(n, new ulong3(k.x, 0, 1)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + Assert.AreEqual(c.z, realbinom(n.z, 1)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x, realbinom(n.x, 1)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 1)); + + c = maxmath.comb(new ulong3(1), new ulong3(0)); + Assert.AreEqual(c.x, realbinom(1, 0)); + Assert.AreEqual(c.y, realbinom(1, 0)); + Assert.AreEqual(c.z, realbinom(1, 0)); + + c = maxmath.comb(new ulong3(1), new ulong3(1)); + Assert.AreEqual(c.x, realbinom(1, 1)); + Assert.AreEqual(c.y, realbinom(1, 1)); + Assert.AreEqual(c.z, realbinom(1, 1)); + } + } + + [Test] + public static void _ulong4() + { + Random64 rng = Random64.New; + + for (int i = 0; i < 4; i++) + { + ulong4 n = rng.NextULong4(1, ulong.MaxValue); + ulong4 k = n - 1; + ulong4 c; + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, n.x); + Assert.AreEqual(c.y, n.y); + Assert.AreEqual(c.z, n.z); + Assert.AreEqual(c.w, n.w); + + n = rng.NextULong4(1, ulong.MaxValue); + k = rng.NextULong4(0, n + 1); + k = maxmath.select(k, n - 1000, n - k > 1000); + + c = maxmath.comb(n, k); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, k.y)); + Assert.AreEqual(c.z, realbinom(n.z, k.z)); + Assert.AreEqual(c.w, realbinom(n.w, k.w)); + + c = maxmath.comb(n, k); + Assert.AreEqual(maxmath.comb(n, 0).x, realbinom(n.x, 0)); + Assert.AreEqual(maxmath.comb(n, 0).y, realbinom(n.y, 0)); + Assert.AreEqual(maxmath.comb(n, 0).z, realbinom(n.z, 0)); + Assert.AreEqual(maxmath.comb(n, 0).w, realbinom(n.w, 0)); + + c = maxmath.comb(n, new ulong4(0, 1, 0, 1)); + Assert.AreEqual(c.x, realbinom(n.x, 0)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 0)); + Assert.AreEqual(c.w, realbinom(n.w, 1)); + + c = maxmath.comb(n, new ulong4(k.x, 1, 0, 1)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 0)); + Assert.AreEqual(c.w, realbinom(n.w, 1)); + + c = maxmath.comb(n, new ulong4(k.x, 0, 1, 0)); + Assert.AreEqual(c.x, realbinom(n.x, k.x)); + Assert.AreEqual(c.y, realbinom(n.y, 0)); + Assert.AreEqual(c.z, realbinom(n.z, 1)); + Assert.AreEqual(c.w, realbinom(n.w, 0)); + + c = maxmath.comb(n, 1); + Assert.AreEqual(c.x, realbinom(n.x, 1)); + Assert.AreEqual(c.y, realbinom(n.y, 1)); + Assert.AreEqual(c.z, realbinom(n.z, 1)); + Assert.AreEqual(c.w, realbinom(n.w, 1)); + + c = maxmath.comb(new ulong4(1), new ulong4(0)); + Assert.AreEqual(c.x, realbinom(1, 0)); + Assert.AreEqual(c.y, realbinom(1, 0)); + Assert.AreEqual(c.z, realbinom(1, 0)); + Assert.AreEqual(c.w, realbinom(1, 0)); + + c = maxmath.comb(new ulong4(1), new ulong4(1)); + Assert.AreEqual(c.x, realbinom(1, 1)); + Assert.AreEqual(c.y, realbinom(1, 1)); + Assert.AreEqual(c.z, realbinom(1, 1)); + Assert.AreEqual(c.w, realbinom(1, 1)); + } + } + } +} diff --git a/Tests/Editor/Functions/Arithmetic/Integer/comb.cs.meta b/Tests/Editor/Functions/Arithmetic/Integer/comb.cs.meta new file mode 100644 index 0000000..5832383 --- /dev/null +++ b/Tests/Editor/Functions/Arithmetic/Integer/comb.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0331de407a2090445b8384bdba2a29b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Editor/Functions/Arithmetic/Integer/factorial.cs b/Tests/Editor/Functions/Arithmetic/Integer/factorial.cs index 1ae1c43..f63868b 100644 --- a/Tests/Editor/Functions/Arithmetic/Integer/factorial.cs +++ b/Tests/Editor/Functions/Arithmetic/Integer/factorial.cs @@ -1,5 +1,4 @@ using NUnit.Framework; -using Unity.Burst.CompilerServices; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Arithmetic/Integer/perm.cs b/Tests/Editor/Functions/Arithmetic/Integer/perm.cs new file mode 100644 index 0000000..48b815d --- /dev/null +++ b/Tests/Editor/Functions/Arithmetic/Integer/perm.cs @@ -0,0 +1,761 @@ +using NUnit.Framework; +using Unity.Mathematics; + +namespace MaxMath.Tests +{ + unsafe public static class perm + { + [Test] + public static void _ulong2() + { + Random64 rng = Random64.New; + + for (int i = 0; i < 25; i++) + { + ulong2 n = rng.NextULong2(1, 100); + ulong2 k = rng.NextULong2(0, maxmath.min(rng.NextULong2(0, 100), n)); + + ulong2 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x, maxmath.perm(n.x, k.x)); + Assert.AreEqual(p.y, maxmath.perm(n.y, k.y)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, n.y); + + p = maxmath.perm(n, new ulong2(1, k.y)); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, maxmath.perm(n.y, k.y)); + } + } + + [Test] + public static void _ulong3() + { + Random64 rng = Random64.New; + + for (int i = 0; i < 25; i++) + { + ulong3 n = rng.NextULong3(1, 100); + ulong3 k = rng.NextULong3(0, maxmath.min(rng.NextULong3(0, 100), n)); + + ulong3 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x, maxmath.perm(n.x, k.x)); + Assert.AreEqual(p.y, maxmath.perm(n.y, k.y)); + Assert.AreEqual(p.z, maxmath.perm(n.z, k.z)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, n.y); + Assert.AreEqual(p.z, n.z); + + p = maxmath.perm(n, new ulong3(1, k.y, 1)); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, maxmath.perm(n.y, k.y)); + Assert.AreEqual(p.z, n.z); + } + } + + [Test] + public static void _ulong4() + { + Random64 rng = Random64.New; + + for (int i = 0; i < 25; i++) + { + ulong4 n = rng.NextULong4(1, 100); + ulong4 k = rng.NextULong4(0, maxmath.min(rng.NextULong4(0, 100), n)); + + ulong4 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x, maxmath.perm(n.x, k.x)); + Assert.AreEqual(p.y, maxmath.perm(n.y, k.y)); + Assert.AreEqual(p.z, maxmath.perm(n.z, k.z)); + Assert.AreEqual(p.w, maxmath.perm(n.w, k.w)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, n.y); + Assert.AreEqual(p.z, n.z); + Assert.AreEqual(p.w, n.w); + + p = maxmath.perm(n, new ulong4(1, k.y, 1, k.w)); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, maxmath.perm(n.y, k.y)); + Assert.AreEqual(p.z, n.z); + Assert.AreEqual(p.w, maxmath.perm(n.w, k.w)); + } + } + + + [Test] + public static void _uint2() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 25; i++) + { + uint2 n = rng.NextUInt2(1, 100); + uint2 k = rng.NextUInt2(0, math.min(rng.NextUInt2(0, 100), n)); + + uint2 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x, maxmath.perm(n.x, k.x)); + Assert.AreEqual(p.y, maxmath.perm(n.y, k.y)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, n.y); + + p = maxmath.perm(n, new uint2(1, k.y)); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, maxmath.perm(n.y, k.y)); + } + } + + [Test] + public static void _uint3() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 25; i++) + { + uint3 n = rng.NextUInt3(1, 100); + uint3 k = rng.NextUInt3(0, math.min(rng.NextUInt3(0, 100), n)); + + uint3 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x, maxmath.perm(n.x, k.x)); + Assert.AreEqual(p.y, maxmath.perm(n.y, k.y)); + Assert.AreEqual(p.z, maxmath.perm(n.z, k.z)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, n.y); + Assert.AreEqual(p.z, n.z); + + p = maxmath.perm(n, new uint3(1, k.y, 1)); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, maxmath.perm(n.y, k.y)); + Assert.AreEqual(p.z, n.z); + } + } + + [Test] + public static void _uint4() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 25; i++) + { + uint4 n = rng.NextUInt4(1, 100); + uint4 k = rng.NextUInt4(0, math.min(rng.NextUInt4(0, 100), n)); + + uint4 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x, maxmath.perm(n.x, k.x)); + Assert.AreEqual(p.y, maxmath.perm(n.y, k.y)); + Assert.AreEqual(p.z, maxmath.perm(n.z, k.z)); + Assert.AreEqual(p.w, maxmath.perm(n.w, k.w)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, n.y); + Assert.AreEqual(p.z, n.z); + Assert.AreEqual(p.w, n.w); + + p = maxmath.perm(n, new uint4(1, k.y, 1, k.w)); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, maxmath.perm(n.y, k.y)); + Assert.AreEqual(p.z, n.z); + Assert.AreEqual(p.w, maxmath.perm(n.w, k.w)); + } + } + + [Test] + public static void _uint8() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 25; i++) + { + uint8 n = rng.NextUInt8(1, 100); + uint8 k = rng.NextUInt8(0, maxmath.min(rng.NextUInt8(0, 100), n)); + + uint8 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x0, maxmath.perm(n.x0, k.x0)); + Assert.AreEqual(p.x1, maxmath.perm(n.x1, k.x1)); + Assert.AreEqual(p.x2, maxmath.perm(n.x2, k.x2)); + Assert.AreEqual(p.x3, maxmath.perm(n.x3, k.x3)); + Assert.AreEqual(p.x4, maxmath.perm(n.x4, k.x4)); + Assert.AreEqual(p.x5, maxmath.perm(n.x5, k.x5)); + Assert.AreEqual(p.x6, maxmath.perm(n.x6, k.x6)); + Assert.AreEqual(p.x7, maxmath.perm(n.x7, k.x7)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x0, n.x0); + Assert.AreEqual(p.x1, n.x1); + Assert.AreEqual(p.x2, n.x2); + Assert.AreEqual(p.x3, n.x3); + Assert.AreEqual(p.x4, n.x4); + Assert.AreEqual(p.x5, n.x5); + Assert.AreEqual(p.x6, n.x6); + Assert.AreEqual(p.x7, n.x7); + + p = maxmath.perm(n, new uint8(1, k.x1, 1, k.x3, 1, k.x5, 1, k.x7)); + + Assert.AreEqual(p.x0, n.x0); + Assert.AreEqual(p.x1, maxmath.perm(n.x1, k.x1)); + Assert.AreEqual(p.x2, n.x2); + Assert.AreEqual(p.x3, maxmath.perm(n.x3, k.x3)); + Assert.AreEqual(p.x4, n.x4); + Assert.AreEqual(p.x5, maxmath.perm(n.x5, k.x5)); + Assert.AreEqual(p.x6, n.x6); + Assert.AreEqual(p.x7, maxmath.perm(n.x7, k.x7)); + } + } + + + [Test] + public static void _ushort2() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + ushort2 n = rng.NextUShort2(1, 100); + ushort2 k = rng.NextUShort2(0, maxmath.min(rng.NextUShort2(0, 100), n)); + + ushort2 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x, (ushort)maxmath.perm((uint)n.x, (uint)k.x)); + Assert.AreEqual(p.y, (ushort)maxmath.perm((uint)n.y, (uint)k.y)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, n.y); + + p = maxmath.perm(n, new ushort2(1, k.y)); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, (ushort)maxmath.perm((uint)n.y, (uint)k.y)); + } + } + + [Test] + public static void _ushort3() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + ushort3 n = rng.NextUShort3(1, 100); + ushort3 k = rng.NextUShort3(0, maxmath.min(rng.NextUShort3(0, 100), n)); + + ushort3 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x, (ushort)maxmath.perm((uint)n.x, (uint)k.x)); + Assert.AreEqual(p.y, (ushort)maxmath.perm((uint)n.y, (uint)k.y)); + Assert.AreEqual(p.z, (ushort)maxmath.perm((uint)n.z, (uint)k.z)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, n.y); + Assert.AreEqual(p.z, n.z); + + p = maxmath.perm(n, new ushort3(1, k.y, 1)); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, (ushort)maxmath.perm((uint)n.y, (uint)k.y)); + Assert.AreEqual(p.z, n.z); + } + } + + [Test] + public static void _ushort4() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + ushort4 n = rng.NextUShort4(1, 100); + ushort4 k = rng.NextUShort4(0, maxmath.min(rng.NextUShort4(0, 100), n)); + + ushort4 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x, (ushort)maxmath.perm((uint)n.x, (uint)k.x)); + Assert.AreEqual(p.y, (ushort)maxmath.perm((uint)n.y, (uint)k.y)); + Assert.AreEqual(p.z, (ushort)maxmath.perm((uint)n.z, (uint)k.z)); + Assert.AreEqual(p.w, (ushort)maxmath.perm((uint)n.w, (uint)k.w)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, n.y); + Assert.AreEqual(p.z, n.z); + Assert.AreEqual(p.w, n.w); + + p = maxmath.perm(n, new ushort4(1, k.y, 1, k.w)); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, (ushort)maxmath.perm((uint)n.y, (uint)k.y)); + Assert.AreEqual(p.z, n.z); + Assert.AreEqual(p.w, (ushort)maxmath.perm((uint)n.w, (uint)k.w)); + } + } + + [Test] + public static void _ushort8() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + ushort8 n = rng.NextUShort8(1, 100); + ushort8 k = rng.NextUShort8(0, maxmath.min(rng.NextUShort8(0, 100), n)); + + ushort8 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x0, (ushort)maxmath.perm((uint)n.x0, (uint)k.x0)); + Assert.AreEqual(p.x1, (ushort)maxmath.perm((uint)n.x1, (uint)k.x1)); + Assert.AreEqual(p.x2, (ushort)maxmath.perm((uint)n.x2, (uint)k.x2)); + Assert.AreEqual(p.x3, (ushort)maxmath.perm((uint)n.x3, (uint)k.x3)); + Assert.AreEqual(p.x4, (ushort)maxmath.perm((uint)n.x4, (uint)k.x4)); + Assert.AreEqual(p.x5, (ushort)maxmath.perm((uint)n.x5, (uint)k.x5)); + Assert.AreEqual(p.x6, (ushort)maxmath.perm((uint)n.x6, (uint)k.x6)); + Assert.AreEqual(p.x7, (ushort)maxmath.perm((uint)n.x7, (uint)k.x7)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x0, n.x0); + Assert.AreEqual(p.x1, n.x1); + Assert.AreEqual(p.x2, n.x2); + Assert.AreEqual(p.x3, n.x3); + Assert.AreEqual(p.x4, n.x4); + Assert.AreEqual(p.x5, n.x5); + Assert.AreEqual(p.x6, n.x6); + Assert.AreEqual(p.x7, n.x7); + + p = maxmath.perm(n, new ushort8(1, k.x1, 1, k.x3, 1, k.x5, 1, k.x7)); + + Assert.AreEqual(p.x0, n.x0); + Assert.AreEqual(p.x1, (ushort)maxmath.perm((uint)n.x1, (uint)k.x1)); + Assert.AreEqual(p.x2, n.x2); + Assert.AreEqual(p.x3, (ushort)maxmath.perm((uint)n.x3, (uint)k.x3)); + Assert.AreEqual(p.x4, n.x4); + Assert.AreEqual(p.x5, (ushort)maxmath.perm((uint)n.x5, (uint)k.x5)); + Assert.AreEqual(p.x6, n.x6); + Assert.AreEqual(p.x7, (ushort)maxmath.perm((uint)n.x7, (uint)k.x7)); + } + } + + [Test] + public static void _ushort16() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + ushort16 n = rng.NextUShort16(1, 100); + ushort16 k = rng.NextUShort16(0, maxmath.min(rng.NextUShort16(0, 100), n)); + + ushort16 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x0, (ushort)maxmath.perm((uint)n.x0, (uint)k.x0)); + Assert.AreEqual(p.x1, (ushort)maxmath.perm((uint)n.x1, (uint)k.x1)); + Assert.AreEqual(p.x2, (ushort)maxmath.perm((uint)n.x2, (uint)k.x2)); + Assert.AreEqual(p.x3, (ushort)maxmath.perm((uint)n.x3, (uint)k.x3)); + Assert.AreEqual(p.x4, (ushort)maxmath.perm((uint)n.x4, (uint)k.x4)); + Assert.AreEqual(p.x5, (ushort)maxmath.perm((uint)n.x5, (uint)k.x5)); + Assert.AreEqual(p.x6, (ushort)maxmath.perm((uint)n.x6, (uint)k.x6)); + Assert.AreEqual(p.x7, (ushort)maxmath.perm((uint)n.x7, (uint)k.x7)); + Assert.AreEqual(p.x8, (ushort)maxmath.perm((uint)n.x8, (uint)k.x8)); + Assert.AreEqual(p.x9, (ushort)maxmath.perm((uint)n.x9, (uint)k.x9)); + Assert.AreEqual(p.x10, (ushort)maxmath.perm((uint)n.x10, (uint)k.x10)); + Assert.AreEqual(p.x11, (ushort)maxmath.perm((uint)n.x11, (uint)k.x11)); + Assert.AreEqual(p.x12, (ushort)maxmath.perm((uint)n.x12, (uint)k.x12)); + Assert.AreEqual(p.x13, (ushort)maxmath.perm((uint)n.x13, (uint)k.x13)); + Assert.AreEqual(p.x14, (ushort)maxmath.perm((uint)n.x14, (uint)k.x14)); + Assert.AreEqual(p.x15, (ushort)maxmath.perm((uint)n.x15, (uint)k.x15)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x0, n.x0); + Assert.AreEqual(p.x1, n.x1); + Assert.AreEqual(p.x2, n.x2); + Assert.AreEqual(p.x3, n.x3); + Assert.AreEqual(p.x4, n.x4); + Assert.AreEqual(p.x5, n.x5); + Assert.AreEqual(p.x6, n.x6); + Assert.AreEqual(p.x7, n.x7); + Assert.AreEqual(p.x8, n.x8); + Assert.AreEqual(p.x9, n.x9); + Assert.AreEqual(p.x10, n.x10); + Assert.AreEqual(p.x11, n.x11); + Assert.AreEqual(p.x12, n.x12); + Assert.AreEqual(p.x13, n.x13); + Assert.AreEqual(p.x14, n.x14); + Assert.AreEqual(p.x15, n.x15); + + p = maxmath.perm(n, new ushort16(1, k.x1, 1, k.x3, 1, k.x5, 1, k.x7, 1, k.x9, 1, k.x11, 1, k.x13, 1, k.x15)); + + Assert.AreEqual(p.x0, n.x0); + Assert.AreEqual(p.x1, (ushort)maxmath.perm((uint)n.x1, (uint)k.x1)); + Assert.AreEqual(p.x2, n.x2); + Assert.AreEqual(p.x3, (ushort)maxmath.perm((uint)n.x3, (uint)k.x3)); + Assert.AreEqual(p.x4, n.x4); + Assert.AreEqual(p.x5, (ushort)maxmath.perm((uint)n.x5, (uint)k.x5)); + Assert.AreEqual(p.x6, n.x6); + Assert.AreEqual(p.x7, (ushort)maxmath.perm((uint)n.x7, (uint)k.x7)); + Assert.AreEqual(p.x8, n.x8); + Assert.AreEqual(p.x9, (ushort)maxmath.perm((uint)n.x9, (uint)k.x9)); + Assert.AreEqual(p.x10, n.x10); + Assert.AreEqual(p.x11, (ushort)maxmath.perm((uint)n.x11, (uint)k.x11)); + Assert.AreEqual(p.x12, n.x12); + Assert.AreEqual(p.x13, (ushort)maxmath.perm((uint)n.x13, (uint)k.x13)); + Assert.AreEqual(p.x14, n.x14); + Assert.AreEqual(p.x15, (ushort)maxmath.perm((uint)n.x15, (uint)k.x15)); + } + } + + + [Test] + public static void _byte2() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + byte2 n = rng.NextByte2(1, 100); + byte2 k = rng.NextByte2(0, maxmath.min(rng.NextByte2(0, 100), n)); + + byte2 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x, (byte)maxmath.perm((uint)n.x, (uint)k.x)); + Assert.AreEqual(p.y, (byte)maxmath.perm((uint)n.y, (uint)k.y)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, n.y); + + p = maxmath.perm(n, new byte2(1, k.y)); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, (byte)maxmath.perm((uint)n.y, (uint)k.y)); + } + } + + [Test] + public static void _byte3() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + byte3 n = rng.NextByte3(1, 100); + byte3 k = rng.NextByte3(0, maxmath.min(rng.NextByte3(0, 100), n)); + + byte3 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x, (byte)maxmath.perm((uint)n.x, (uint)k.x)); + Assert.AreEqual(p.y, (byte)maxmath.perm((uint)n.y, (uint)k.y)); + Assert.AreEqual(p.z, (byte)maxmath.perm((uint)n.z, (uint)k.z)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, n.y); + Assert.AreEqual(p.z, n.z); + + p = maxmath.perm(n, new byte3(1, k.y, 1)); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, (byte)maxmath.perm((uint)n.y, (uint)k.y)); + Assert.AreEqual(p.z, n.z); + } + } + + [Test] + public static void _byte4() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + byte4 n = rng.NextByte4(1, 100); + byte4 k = rng.NextByte4(0, maxmath.min(rng.NextByte4(0, 100), n)); + + byte4 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x, (byte)maxmath.perm((uint)n.x, (uint)k.x)); + Assert.AreEqual(p.y, (byte)maxmath.perm((uint)n.y, (uint)k.y)); + Assert.AreEqual(p.z, (byte)maxmath.perm((uint)n.z, (uint)k.z)); + Assert.AreEqual(p.w, (byte)maxmath.perm((uint)n.w, (uint)k.w)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, n.y); + Assert.AreEqual(p.z, n.z); + Assert.AreEqual(p.w, n.w); + + p = maxmath.perm(n, new byte4(1, k.y, 1, k.w)); + + Assert.AreEqual(p.x, n.x); + Assert.AreEqual(p.y, (byte)maxmath.perm((uint)n.y, (uint)k.y)); + Assert.AreEqual(p.z, n.z); + Assert.AreEqual(p.w, (byte)maxmath.perm((uint)n.w, (uint)k.w)); + } + } + + [Test] + public static void _byte8() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + byte8 n = rng.NextByte8(1, 100); + byte8 k = rng.NextByte8(0, maxmath.min(rng.NextByte8(0, 100), n)); + + byte8 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x0, (byte)maxmath.perm((uint)n.x0, (uint)k.x0)); + Assert.AreEqual(p.x1, (byte)maxmath.perm((uint)n.x1, (uint)k.x1)); + Assert.AreEqual(p.x2, (byte)maxmath.perm((uint)n.x2, (uint)k.x2)); + Assert.AreEqual(p.x3, (byte)maxmath.perm((uint)n.x3, (uint)k.x3)); + Assert.AreEqual(p.x4, (byte)maxmath.perm((uint)n.x4, (uint)k.x4)); + Assert.AreEqual(p.x5, (byte)maxmath.perm((uint)n.x5, (uint)k.x5)); + Assert.AreEqual(p.x6, (byte)maxmath.perm((uint)n.x6, (uint)k.x6)); + Assert.AreEqual(p.x7, (byte)maxmath.perm((uint)n.x7, (uint)k.x7)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x0, n.x0); + Assert.AreEqual(p.x1, n.x1); + Assert.AreEqual(p.x2, n.x2); + Assert.AreEqual(p.x3, n.x3); + Assert.AreEqual(p.x4, n.x4); + Assert.AreEqual(p.x5, n.x5); + Assert.AreEqual(p.x6, n.x6); + Assert.AreEqual(p.x7, n.x7); + + p = maxmath.perm(n, new byte8(1, k.x1, 1, k.x3, 1, k.x5, 1, k.x7)); + + Assert.AreEqual(p.x0, n.x0); + Assert.AreEqual(p.x1, (byte)maxmath.perm((uint)n.x1, (uint)k.x1)); + Assert.AreEqual(p.x2, n.x2); + Assert.AreEqual(p.x3, (byte)maxmath.perm((uint)n.x3, (uint)k.x3)); + Assert.AreEqual(p.x4, n.x4); + Assert.AreEqual(p.x5, (byte)maxmath.perm((uint)n.x5, (uint)k.x5)); + Assert.AreEqual(p.x6, n.x6); + Assert.AreEqual(p.x7, (byte)maxmath.perm((uint)n.x7, (uint)k.x7)); + } + } + + [Test] + public static void _byte16() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + byte16 n = rng.NextByte16(1, 100); + byte16 k = rng.NextByte16(0, maxmath.min(rng.NextByte16(0, 100), n)); + + byte16 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x0, (byte)maxmath.perm((uint)n.x0, (uint)k.x0)); + Assert.AreEqual(p.x1, (byte)maxmath.perm((uint)n.x1, (uint)k.x1)); + Assert.AreEqual(p.x2, (byte)maxmath.perm((uint)n.x2, (uint)k.x2)); + Assert.AreEqual(p.x3, (byte)maxmath.perm((uint)n.x3, (uint)k.x3)); + Assert.AreEqual(p.x4, (byte)maxmath.perm((uint)n.x4, (uint)k.x4)); + Assert.AreEqual(p.x5, (byte)maxmath.perm((uint)n.x5, (uint)k.x5)); + Assert.AreEqual(p.x6, (byte)maxmath.perm((uint)n.x6, (uint)k.x6)); + Assert.AreEqual(p.x7, (byte)maxmath.perm((uint)n.x7, (uint)k.x7)); + Assert.AreEqual(p.x8, (byte)maxmath.perm((uint)n.x8, (uint)k.x8)); + Assert.AreEqual(p.x9, (byte)maxmath.perm((uint)n.x9, (uint)k.x9)); + Assert.AreEqual(p.x10, (byte)maxmath.perm((uint)n.x10, (uint)k.x10)); + Assert.AreEqual(p.x11, (byte)maxmath.perm((uint)n.x11, (uint)k.x11)); + Assert.AreEqual(p.x12, (byte)maxmath.perm((uint)n.x12, (uint)k.x12)); + Assert.AreEqual(p.x13, (byte)maxmath.perm((uint)n.x13, (uint)k.x13)); + Assert.AreEqual(p.x14, (byte)maxmath.perm((uint)n.x14, (uint)k.x14)); + Assert.AreEqual(p.x15, (byte)maxmath.perm((uint)n.x15, (uint)k.x15)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x0, n.x0); + Assert.AreEqual(p.x1, n.x1); + Assert.AreEqual(p.x2, n.x2); + Assert.AreEqual(p.x3, n.x3); + Assert.AreEqual(p.x4, n.x4); + Assert.AreEqual(p.x5, n.x5); + Assert.AreEqual(p.x6, n.x6); + Assert.AreEqual(p.x7, n.x7); + Assert.AreEqual(p.x8, n.x8); + Assert.AreEqual(p.x9, n.x9); + Assert.AreEqual(p.x10, n.x10); + Assert.AreEqual(p.x11, n.x11); + Assert.AreEqual(p.x12, n.x12); + Assert.AreEqual(p.x13, n.x13); + Assert.AreEqual(p.x14, n.x14); + Assert.AreEqual(p.x15, n.x15); + + p = maxmath.perm(n, new byte16(1, k.x1, 1, k.x3, 1, k.x5, 1, k.x7, 1, k.x9, 1, k.x11, 1, k.x13, 1, k.x15)); + + Assert.AreEqual(p.x0, n.x0); + Assert.AreEqual(p.x1, (byte)maxmath.perm((uint)n.x1, (uint)k.x1)); + Assert.AreEqual(p.x2, n.x2); + Assert.AreEqual(p.x3, (byte)maxmath.perm((uint)n.x3, (uint)k.x3)); + Assert.AreEqual(p.x4, n.x4); + Assert.AreEqual(p.x5, (byte)maxmath.perm((uint)n.x5, (uint)k.x5)); + Assert.AreEqual(p.x6, n.x6); + Assert.AreEqual(p.x7, (byte)maxmath.perm((uint)n.x7, (uint)k.x7)); + Assert.AreEqual(p.x8, n.x8); + Assert.AreEqual(p.x9, (byte)maxmath.perm((uint)n.x9, (uint)k.x9)); + Assert.AreEqual(p.x10, n.x10); + Assert.AreEqual(p.x11, (byte)maxmath.perm((uint)n.x11, (uint)k.x11)); + Assert.AreEqual(p.x12, n.x12); + Assert.AreEqual(p.x13, (byte)maxmath.perm((uint)n.x13, (uint)k.x13)); + Assert.AreEqual(p.x14, n.x14); + Assert.AreEqual(p.x15, (byte)maxmath.perm((uint)n.x15, (uint)k.x15)); + } + } + + [Test] + public static void _byte32() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + byte32 n = rng.NextByte32(1, 100); + byte32 k = rng.NextByte32(0, maxmath.min(rng.NextByte32(0, 100), n)); + + byte32 p = maxmath.perm(n, k); + + Assert.AreEqual(p.x0, (byte)maxmath.perm((uint)n.x0, (uint)k.x0)); + Assert.AreEqual(p.x1, (byte)maxmath.perm((uint)n.x1, (uint)k.x1)); + Assert.AreEqual(p.x2, (byte)maxmath.perm((uint)n.x2, (uint)k.x2)); + Assert.AreEqual(p.x3, (byte)maxmath.perm((uint)n.x3, (uint)k.x3)); + Assert.AreEqual(p.x4, (byte)maxmath.perm((uint)n.x4, (uint)k.x4)); + Assert.AreEqual(p.x5, (byte)maxmath.perm((uint)n.x5, (uint)k.x5)); + Assert.AreEqual(p.x6, (byte)maxmath.perm((uint)n.x6, (uint)k.x6)); + Assert.AreEqual(p.x7, (byte)maxmath.perm((uint)n.x7, (uint)k.x7)); + Assert.AreEqual(p.x8, (byte)maxmath.perm((uint)n.x8, (uint)k.x8)); + Assert.AreEqual(p.x9, (byte)maxmath.perm((uint)n.x9, (uint)k.x9)); + Assert.AreEqual(p.x10, (byte)maxmath.perm((uint)n.x10, (uint)k.x10)); + Assert.AreEqual(p.x11, (byte)maxmath.perm((uint)n.x11, (uint)k.x11)); + Assert.AreEqual(p.x12, (byte)maxmath.perm((uint)n.x12, (uint)k.x12)); + Assert.AreEqual(p.x13, (byte)maxmath.perm((uint)n.x13, (uint)k.x13)); + Assert.AreEqual(p.x14, (byte)maxmath.perm((uint)n.x14, (uint)k.x14)); + Assert.AreEqual(p.x15, (byte)maxmath.perm((uint)n.x15, (uint)k.x15)); + Assert.AreEqual(p.x16, (byte)maxmath.perm((uint)n.x16, (uint)k.x16)); + Assert.AreEqual(p.x17, (byte)maxmath.perm((uint)n.x17, (uint)k.x17)); + Assert.AreEqual(p.x18, (byte)maxmath.perm((uint)n.x18, (uint)k.x18)); + Assert.AreEqual(p.x19, (byte)maxmath.perm((uint)n.x19, (uint)k.x19)); + Assert.AreEqual(p.x20, (byte)maxmath.perm((uint)n.x20, (uint)k.x20)); + Assert.AreEqual(p.x21, (byte)maxmath.perm((uint)n.x21, (uint)k.x21)); + Assert.AreEqual(p.x22, (byte)maxmath.perm((uint)n.x22, (uint)k.x22)); + Assert.AreEqual(p.x23, (byte)maxmath.perm((uint)n.x23, (uint)k.x23)); + Assert.AreEqual(p.x24, (byte)maxmath.perm((uint)n.x24, (uint)k.x24)); + Assert.AreEqual(p.x25, (byte)maxmath.perm((uint)n.x25, (uint)k.x25)); + Assert.AreEqual(p.x26, (byte)maxmath.perm((uint)n.x26, (uint)k.x26)); + Assert.AreEqual(p.x27, (byte)maxmath.perm((uint)n.x27, (uint)k.x27)); + Assert.AreEqual(p.x28, (byte)maxmath.perm((uint)n.x28, (uint)k.x28)); + Assert.AreEqual(p.x29, (byte)maxmath.perm((uint)n.x29, (uint)k.x29)); + Assert.AreEqual(p.x30, (byte)maxmath.perm((uint)n.x30, (uint)k.x30)); + Assert.AreEqual(p.x31, (byte)maxmath.perm((uint)n.x31, (uint)k.x31)); + + p = maxmath.perm(n, 1); + + Assert.AreEqual(p.x0, n.x0); + Assert.AreEqual(p.x1, n.x1); + Assert.AreEqual(p.x2, n.x2); + Assert.AreEqual(p.x3, n.x3); + Assert.AreEqual(p.x4, n.x4); + Assert.AreEqual(p.x5, n.x5); + Assert.AreEqual(p.x6, n.x6); + Assert.AreEqual(p.x7, n.x7); + Assert.AreEqual(p.x8, n.x8); + Assert.AreEqual(p.x9, n.x9); + Assert.AreEqual(p.x10, n.x10); + Assert.AreEqual(p.x11, n.x11); + Assert.AreEqual(p.x12, n.x12); + Assert.AreEqual(p.x13, n.x13); + Assert.AreEqual(p.x14, n.x14); + Assert.AreEqual(p.x15, n.x15); + Assert.AreEqual(p.x16, n.x16); + Assert.AreEqual(p.x17, n.x17); + Assert.AreEqual(p.x18, n.x18); + Assert.AreEqual(p.x19, n.x19); + Assert.AreEqual(p.x20, n.x20); + Assert.AreEqual(p.x21, n.x21); + Assert.AreEqual(p.x22, n.x22); + Assert.AreEqual(p.x23, n.x23); + Assert.AreEqual(p.x24, n.x24); + Assert.AreEqual(p.x25, n.x25); + Assert.AreEqual(p.x26, n.x26); + Assert.AreEqual(p.x27, n.x27); + Assert.AreEqual(p.x28, n.x28); + Assert.AreEqual(p.x29, n.x29); + Assert.AreEqual(p.x30, n.x30); + Assert.AreEqual(p.x31, n.x31); + + p = maxmath.perm(n, new byte32(1, k.x1, 1, k.x3, 1, k.x5, 1, k.x7, 1, k.x9, 1, k.x11, 1, k.x13, 1, k.x15, 1, k.x17, 1, k.x19, 1, k.x21, 1, k.x23, 1, k.x25, 1, k.x27, 1, k.x29, 1, k.x31)); + + Assert.AreEqual(p.x0, n.x0); + Assert.AreEqual(p.x1, (byte)maxmath.perm((uint)n.x1, (uint)k.x1)); + Assert.AreEqual(p.x2, n.x2); + Assert.AreEqual(p.x3, (byte)maxmath.perm((uint)n.x3, (uint)k.x3)); + Assert.AreEqual(p.x4, n.x4); + Assert.AreEqual(p.x5, (byte)maxmath.perm((uint)n.x5, (uint)k.x5)); + Assert.AreEqual(p.x6, n.x6); + Assert.AreEqual(p.x7, (byte)maxmath.perm((uint)n.x7, (uint)k.x7)); + Assert.AreEqual(p.x8, n.x8); + Assert.AreEqual(p.x9, (byte)maxmath.perm((uint)n.x9, (uint)k.x9)); + Assert.AreEqual(p.x10, n.x10); + Assert.AreEqual(p.x11, (byte)maxmath.perm((uint)n.x11, (uint)k.x11)); + Assert.AreEqual(p.x12, n.x12); + Assert.AreEqual(p.x13, (byte)maxmath.perm((uint)n.x13, (uint)k.x13)); + Assert.AreEqual(p.x14, n.x14); + Assert.AreEqual(p.x15, (byte)maxmath.perm((uint)n.x15, (uint)k.x15)); + Assert.AreEqual(p.x16, n.x16); + Assert.AreEqual(p.x17, (byte)maxmath.perm((uint)n.x17, (uint)k.x17)); + Assert.AreEqual(p.x18, n.x18); + Assert.AreEqual(p.x19, (byte)maxmath.perm((uint)n.x19, (uint)k.x19)); + Assert.AreEqual(p.x20, n.x20); + Assert.AreEqual(p.x21, (byte)maxmath.perm((uint)n.x21, (uint)k.x21)); + Assert.AreEqual(p.x22, n.x22); + Assert.AreEqual(p.x23, (byte)maxmath.perm((uint)n.x23, (uint)k.x23)); + Assert.AreEqual(p.x24, n.x24); + Assert.AreEqual(p.x25, (byte)maxmath.perm((uint)n.x25, (uint)k.x25)); + Assert.AreEqual(p.x26, n.x26); + Assert.AreEqual(p.x27, (byte)maxmath.perm((uint)n.x27, (uint)k.x27)); + Assert.AreEqual(p.x28, n.x28); + Assert.AreEqual(p.x29, (byte)maxmath.perm((uint)n.x29, (uint)k.x29)); + Assert.AreEqual(p.x30, n.x30); + Assert.AreEqual(p.x31, (byte)maxmath.perm((uint)n.x31, (uint)k.x31)); + } + } + } +} diff --git a/Tests/Editor/Functions/Arithmetic/Integer/perm.cs.meta b/Tests/Editor/Functions/Arithmetic/Integer/perm.cs.meta new file mode 100644 index 0000000..23e3708 --- /dev/null +++ b/Tests/Editor/Functions/Arithmetic/Integer/perm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b78b0a7fae5541c489541c9d36d1c3d4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Editor/Functions/Arithmetic/Saturation/divsaturated.cs b/Tests/Editor/Functions/Arithmetic/Saturation/divsaturated.cs index 00c90fa..e8f4c64 100644 --- a/Tests/Editor/Functions/Arithmetic/Saturation/divsaturated.cs +++ b/Tests/Editor/Functions/Arithmetic/Saturation/divsaturated.cs @@ -1,4 +1,3 @@ -using System.Numerics; using NUnit.Framework; using Unity.Mathematics; diff --git a/Tests/Editor/Functions/Arithmetic/Sign.meta b/Tests/Editor/Functions/Arithmetic/Sign.meta new file mode 100644 index 0000000..fd72f3b --- /dev/null +++ b/Tests/Editor/Functions/Arithmetic/Sign.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fdc09d1b9e305114abf93643613ec20b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Editor/Functions/Arithmetic/abs.cs b/Tests/Editor/Functions/Arithmetic/Sign/abs.cs similarity index 100% rename from Tests/Editor/Functions/Arithmetic/abs.cs rename to Tests/Editor/Functions/Arithmetic/Sign/abs.cs diff --git a/Tests/Editor/Functions/Arithmetic/abs.cs.meta b/Tests/Editor/Functions/Arithmetic/Sign/abs.cs.meta similarity index 83% rename from Tests/Editor/Functions/Arithmetic/abs.cs.meta rename to Tests/Editor/Functions/Arithmetic/Sign/abs.cs.meta index 93fcfce..6f05c13 100644 --- a/Tests/Editor/Functions/Arithmetic/abs.cs.meta +++ b/Tests/Editor/Functions/Arithmetic/Sign/abs.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7b1eb71d676159d49bf6d6a9fa287853 +guid: 80e47642794c88f47931379c43bb4017 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Tests/Editor/Functions/Arithmetic/copysign.cs b/Tests/Editor/Functions/Arithmetic/Sign/copysign.cs similarity index 100% rename from Tests/Editor/Functions/Arithmetic/copysign.cs rename to Tests/Editor/Functions/Arithmetic/Sign/copysign.cs diff --git a/Tests/Editor/Functions/Arithmetic/copysign.cs.meta b/Tests/Editor/Functions/Arithmetic/Sign/copysign.cs.meta similarity index 83% rename from Tests/Editor/Functions/Arithmetic/copysign.cs.meta rename to Tests/Editor/Functions/Arithmetic/Sign/copysign.cs.meta index 26039e9..5547d58 100644 --- a/Tests/Editor/Functions/Arithmetic/copysign.cs.meta +++ b/Tests/Editor/Functions/Arithmetic/Sign/copysign.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 03fa5677c68e98a41a7e504a1a482208 +guid: 10b09d5a2751e9e44959f70fbcd6f1fa MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Tests/Editor/Functions/Arithmetic/sign.cs b/Tests/Editor/Functions/Arithmetic/Sign/sign.cs similarity index 100% rename from Tests/Editor/Functions/Arithmetic/sign.cs rename to Tests/Editor/Functions/Arithmetic/Sign/sign.cs diff --git a/Tests/Editor/Functions/Arithmetic/sign.cs.meta b/Tests/Editor/Functions/Arithmetic/Sign/sign.cs.meta similarity index 83% rename from Tests/Editor/Functions/Arithmetic/sign.cs.meta rename to Tests/Editor/Functions/Arithmetic/Sign/sign.cs.meta index 29b75de..63381c2 100644 --- a/Tests/Editor/Functions/Arithmetic/sign.cs.meta +++ b/Tests/Editor/Functions/Arithmetic/Sign/sign.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 37b64eadc48c0d94b9d3f2838940704d +guid: cdfb356cc1e62d742a46f0124ba14f8d MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Tests/Editor/Functions/Arithmetic/divrem.cs b/Tests/Editor/Functions/Arithmetic/divrem.cs index c1e9e56..54ddf93 100644 --- a/Tests/Editor/Functions/Arithmetic/divrem.cs +++ b/Tests/Editor/Functions/Arithmetic/divrem.cs @@ -1,4 +1,3 @@ -using System.Numerics; using NUnit.Framework; using Unity.Mathematics; diff --git a/Tests/Editor/Functions/Arithmetic/nextgreater.cs b/Tests/Editor/Functions/Arithmetic/nextgreater.cs new file mode 100644 index 0000000..cf5859b --- /dev/null +++ b/Tests/Editor/Functions/Arithmetic/nextgreater.cs @@ -0,0 +1,1181 @@ +using NUnit.Framework; +using Unity.Mathematics; + +namespace MaxMath.Tests +{ + public static class nextgreater + { + [Test] + public static void _uint128() + { + Random128 rng = Random128.New; + + Assert.AreEqual(UInt128.MaxValue, maxmath.nextgreater(UInt128.MaxValue)); + + for (int i = 0; i < 5; i++) + { + UInt128 t = rng.NextUInt128(); + + Assert.AreEqual(t == UInt128.MaxValue ? UInt128.MaxValue : t + 1, maxmath.nextgreater(t)); + } + } + + + [Test] + public static void _int128() + { + Random128 rng = Random128.New; + + Assert.AreEqual(Int128.MaxValue, maxmath.nextgreater(Int128.MaxValue)); + + for (int i = 0; i < 5; i++) + { + Int128 t = rng.NextInt128(); + + Assert.AreEqual(t == Int128.MaxValue ? Int128.MaxValue : t + 1, maxmath.nextgreater(t)); + } + } + + + [Test] + public static void _byte() + { + Random8 rng = Random8.New; + + Assert.AreEqual(byte.MaxValue, maxmath.nextgreater(byte.MaxValue)); + + for (int i = 0; i < 5; i++) + { + byte t = rng.NextByte(); + + Assert.AreEqual(t == byte.MaxValue ? byte.MaxValue : (byte)(t + 1), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _byte2() + { + Random8 rng = Random8.New; + + Assert.AreEqual((byte2)byte.MaxValue, maxmath.nextgreater((byte2)byte.MaxValue)); + + for (int i = 0; i < 5; i++) + { + byte2 t = rng.NextByte2(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == byte.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _byte3() + { + Random8 rng = Random8.New; + + Assert.AreEqual((byte3)byte.MaxValue, maxmath.nextgreater((byte3)byte.MaxValue)); + + for (int i = 0; i < 5; i++) + { + byte3 t = rng.NextByte3(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == byte.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _byte4() + { + Random8 rng = Random8.New; + + Assert.AreEqual((byte4)byte.MaxValue, maxmath.nextgreater((byte4)byte.MaxValue)); + + for (int i = 0; i < 5; i++) + { + byte4 t = rng.NextByte4(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == byte.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _byte8() + { + Random8 rng = Random8.New; + + Assert.AreEqual((byte8)byte.MaxValue, maxmath.nextgreater((byte8)byte.MaxValue)); + + for (int i = 0; i < 5; i++) + { + byte8 t = rng.NextByte8(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == byte.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _byte16() + { + Random8 rng = Random8.New; + + Assert.AreEqual((byte16)byte.MaxValue, maxmath.nextgreater((byte16)byte.MaxValue)); + + for (int i = 0; i < 5; i++) + { + byte16 t = rng.NextByte16(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == byte.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _byte32() + { + Random8 rng = Random8.New; + + Assert.AreEqual((byte32)byte.MaxValue, maxmath.nextgreater((byte32)byte.MaxValue)); + + for (int i = 0; i < 5; i++) + { + byte32 t = rng.NextByte32(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == byte.MaxValue), maxmath.nextgreater(t)); + } + } + + + [Test] + public static void _sbyte() + { + Random8 rng = Random8.New; + + Assert.AreEqual(sbyte.MaxValue, maxmath.nextgreater(sbyte.MaxValue)); + + for (int i = 0; i < 5; i++) + { + sbyte t = rng.NextSByte(); + + Assert.AreEqual(t == sbyte.MaxValue ? sbyte.MaxValue : (sbyte)(t + 1), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _sbyte2() + { + Random8 rng = Random8.New; + + Assert.AreEqual((sbyte2)sbyte.MaxValue, maxmath.nextgreater((sbyte2)sbyte.MaxValue)); + + for (int i = 0; i < 5; i++) + { + sbyte2 t = rng.NextSByte2(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == sbyte.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _sbyte3() + { + Random8 rng = Random8.New; + + Assert.AreEqual((sbyte3)sbyte.MaxValue, maxmath.nextgreater((sbyte3)sbyte.MaxValue)); + + for (int i = 0; i < 5; i++) + { + sbyte3 t = rng.NextSByte3(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == sbyte.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _sbyte4() + { + Random8 rng = Random8.New; + + Assert.AreEqual((sbyte4)sbyte.MaxValue, maxmath.nextgreater((sbyte4)sbyte.MaxValue)); + + for (int i = 0; i < 5; i++) + { + sbyte4 t = rng.NextSByte4(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == sbyte.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _sbyte8() + { + Random8 rng = Random8.New; + + Assert.AreEqual((sbyte8)sbyte.MaxValue, maxmath.nextgreater((sbyte8)sbyte.MaxValue)); + + for (int i = 0; i < 5; i++) + { + sbyte8 t = rng.NextSByte8(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == sbyte.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _sbyte16() + { + Random8 rng = Random8.New; + + Assert.AreEqual((sbyte16)sbyte.MaxValue, maxmath.nextgreater((sbyte16)sbyte.MaxValue)); + + for (int i = 0; i < 5; i++) + { + sbyte16 t = rng.NextSByte16(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == sbyte.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _sbyte32() + { + Random8 rng = Random8.New; + + Assert.AreEqual((sbyte32)sbyte.MaxValue, maxmath.nextgreater((sbyte32)sbyte.MaxValue)); + + for (int i = 0; i < 5; i++) + { + sbyte32 t = rng.NextSByte32(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == sbyte.MaxValue), maxmath.nextgreater(t)); + } + } + + + [Test] + public static void _ushort() + { + Random16 rng = Random16.New; + + Assert.AreEqual(ushort.MaxValue, maxmath.nextgreater(ushort.MaxValue)); + + for (int i = 0; i < 5; i++) + { + ushort t = rng.NextUShort(); + + Assert.AreEqual(t == ushort.MaxValue ? ushort.MaxValue : (ushort)(t + 1), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _ushort2() + { + Random16 rng = Random16.New; + + Assert.AreEqual((ushort2)ushort.MaxValue, maxmath.nextgreater((ushort2)ushort.MaxValue)); + + for (int i = 0; i < 5; i++) + { + ushort2 t = rng.NextUShort2(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == ushort.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _ushort3() + { + Random16 rng = Random16.New; + + Assert.AreEqual((ushort3)ushort.MaxValue, maxmath.nextgreater((ushort3)ushort.MaxValue)); + + for (int i = 0; i < 5; i++) + { + ushort3 t = rng.NextUShort3(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == ushort.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _ushort4() + { + Random16 rng = Random16.New; + + Assert.AreEqual((ushort4)ushort.MaxValue, maxmath.nextgreater((ushort4)ushort.MaxValue)); + + for (int i = 0; i < 5; i++) + { + ushort4 t = rng.NextUShort4(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == ushort.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _ushort8() + { + Random16 rng = Random16.New; + + Assert.AreEqual((ushort8)ushort.MaxValue, maxmath.nextgreater((ushort8)ushort.MaxValue)); + + for (int i = 0; i < 5; i++) + { + ushort8 t = rng.NextUShort8(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == ushort.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _ushort16() + { + Random16 rng = Random16.New; + + Assert.AreEqual((ushort16)ushort.MaxValue, maxmath.nextgreater((ushort16)ushort.MaxValue)); + + for (int i = 0; i < 5; i++) + { + ushort16 t = rng.NextUShort16(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == ushort.MaxValue), maxmath.nextgreater(t)); + } + } + + + [Test] + public static void _short() + { + Random16 rng = Random16.New; + + Assert.AreEqual(short.MaxValue, maxmath.nextgreater(short.MaxValue)); + + for (int i = 0; i < 5; i++) + { + short t = rng.NextShort(); + + Assert.AreEqual(t == short.MaxValue ? short.MaxValue : (short)(t + 1), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _short2() + { + Random16 rng = Random16.New; + + Assert.AreEqual((short2)short.MaxValue, maxmath.nextgreater((short2)short.MaxValue)); + + for (int i = 0; i < 5; i++) + { + short2 t = rng.NextShort2(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == short.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _short3() + { + Random16 rng = Random16.New; + + Assert.AreEqual((short3)short.MaxValue, maxmath.nextgreater((short3)short.MaxValue)); + + for (int i = 0; i < 5; i++) + { + short3 t = rng.NextShort3(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == short.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _short4() + { + Random16 rng = Random16.New; + + Assert.AreEqual((short4)short.MaxValue, maxmath.nextgreater((short4)short.MaxValue)); + + for (int i = 0; i < 5; i++) + { + short4 t = rng.NextShort4(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == short.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _short8() + { + Random16 rng = Random16.New; + + Assert.AreEqual((short8)short.MaxValue, maxmath.nextgreater((short8)short.MaxValue)); + + for (int i = 0; i < 5; i++) + { + short8 t = rng.NextShort8(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == short.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _short16() + { + Random16 rng = Random16.New; + + Assert.AreEqual((short16)short.MaxValue, maxmath.nextgreater((short16)short.MaxValue)); + + for (int i = 0; i < 5; i++) + { + short16 t = rng.NextShort16(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == short.MaxValue), maxmath.nextgreater(t)); + } + } + + + [Test] + public static void _uint() + { + Random32 rng = Random32.New; + + Assert.AreEqual(uint.MaxValue, maxmath.nextgreater(uint.MaxValue)); + + for (int i = 0; i < 5; i++) + { + uint t = rng.NextUInt(); + + Assert.AreEqual(t == uint.MaxValue ? uint.MaxValue : (uint)(t + 1), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _uint2() + { + Random32 rng = Random32.New; + + Assert.AreEqual((uint2)uint.MaxValue, maxmath.nextgreater((uint2)uint.MaxValue)); + + for (int i = 0; i < 5; i++) + { + uint2 t = rng.NextUInt2(); + + Assert.AreEqual(math.select(t + 1, t, t == uint.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _uint3() + { + Random32 rng = Random32.New; + + Assert.AreEqual((uint3)uint.MaxValue, maxmath.nextgreater((uint3)uint.MaxValue)); + + for (int i = 0; i < 5; i++) + { + uint3 t = rng.NextUInt3(); + + Assert.AreEqual(math.select(t + 1, t, t == uint.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _uint4() + { + Random32 rng = Random32.New; + + Assert.AreEqual((uint4)uint.MaxValue, maxmath.nextgreater((uint4)uint.MaxValue)); + + for (int i = 0; i < 5; i++) + { + uint4 t = rng.NextUInt4(); + + Assert.AreEqual(math.select(t + 1, t, t == uint.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _uint8() + { + Random32 rng = Random32.New; + + Assert.AreEqual((uint8)uint.MaxValue, maxmath.nextgreater((uint8)uint.MaxValue)); + + for (int i = 0; i < 5; i++) + { + uint8 t = rng.NextUInt8(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == uint.MaxValue), maxmath.nextgreater(t)); + } + } + + + [Test] + public static void _int() + { + Random32 rng = Random32.New; + + Assert.AreEqual(int.MaxValue, maxmath.nextgreater(int.MaxValue)); + + for (int i = 0; i < 5; i++) + { + int t = rng.NextInt(); + + Assert.AreEqual(t == int.MaxValue ? int.MaxValue : (int)(t + 1), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _int2() + { + Random32 rng = Random32.New; + + Assert.AreEqual((int2)int.MaxValue, maxmath.nextgreater((int2)int.MaxValue)); + + for (int i = 0; i < 5; i++) + { + int2 t = rng.NextInt2(); + + Assert.AreEqual(math.select(t + 1, t, t == int.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _int3() + { + Random32 rng = Random32.New; + + Assert.AreEqual((int3)int.MaxValue, maxmath.nextgreater((int3)int.MaxValue)); + + for (int i = 0; i < 5; i++) + { + int3 t = rng.NextInt3(); + + Assert.AreEqual(math.select(t + 1, t, t == int.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _int4() + { + Random32 rng = Random32.New; + + Assert.AreEqual((int4)int.MaxValue, maxmath.nextgreater((int4)int.MaxValue)); + + for (int i = 0; i < 5; i++) + { + int4 t = rng.NextInt4(); + + Assert.AreEqual(math.select(t + 1, t, t == int.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _int8() + { + Random32 rng = Random32.New; + + Assert.AreEqual((int8)int.MaxValue, maxmath.nextgreater((int8)int.MaxValue)); + + for (int i = 0; i < 5; i++) + { + int8 t = rng.NextInt8(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == int.MaxValue), maxmath.nextgreater(t)); + } + } + + + [Test] + public static void _ulong() + { + Random64 rng = Random64.New; + + Assert.AreEqual(ulong.MaxValue, maxmath.nextgreater(ulong.MaxValue)); + + for (int i = 0; i < 5; i++) + { + ulong t = rng.NextULong(); + + Assert.AreEqual(t == ulong.MaxValue ? ulong.MaxValue : (ulong)(t + 1), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _ulong2() + { + Random64 rng = Random64.New; + + Assert.AreEqual((ulong2)ulong.MaxValue, maxmath.nextgreater((ulong2)ulong.MaxValue)); + + for (int i = 0; i < 5; i++) + { + ulong2 t = rng.NextULong2(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == ulong.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _ulong3() + { + Random64 rng = Random64.New; + + Assert.AreEqual((ulong3)ulong.MaxValue, maxmath.nextgreater((ulong3)ulong.MaxValue)); + + for (int i = 0; i < 5; i++) + { + ulong3 t = rng.NextULong3(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == ulong.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _ulong4() + { + Random64 rng = Random64.New; + + Assert.AreEqual((ulong4)ulong.MaxValue, maxmath.nextgreater((ulong4)ulong.MaxValue)); + + for (int i = 0; i < 5; i++) + { + ulong4 t = rng.NextULong4(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == ulong.MaxValue), maxmath.nextgreater(t)); + } + } + + + [Test] + public static void _long() + { + Random64 rng = Random64.New; + + Assert.AreEqual(long.MaxValue, maxmath.nextgreater(long.MaxValue)); + + for (int i = 0; i < 5; i++) + { + long t = rng.NextLong(); + + Assert.AreEqual(t == long.MaxValue ? long.MaxValue : (long)(t + 1), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _long2() + { + Random64 rng = Random64.New; + + Assert.AreEqual((long2)long.MaxValue, maxmath.nextgreater((long2)long.MaxValue)); + + for (int i = 0; i < 5; i++) + { + long2 t = rng.NextLong2(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == long.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _long3() + { + Random64 rng = Random64.New; + + Assert.AreEqual((long3)long.MaxValue, maxmath.nextgreater((long3)long.MaxValue)); + + for (int i = 0; i < 5; i++) + { + long3 t = rng.NextLong3(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == long.MaxValue), maxmath.nextgreater(t)); + } + } + + [Test] + public static void _long4() + { + Random64 rng = Random64.New; + + Assert.AreEqual((long4)long.MaxValue, maxmath.nextgreater((long4)long.MaxValue)); + + for (int i = 0; i < 5; i++) + { + long4 t = rng.NextLong4(); + + Assert.AreEqual(maxmath.select(t + 1, t, t == long.MaxValue), maxmath.nextgreater(t)); + } + } + + + [Test] + public static void _quarter() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextgreater(maxmath.asquarter((byte)0b0111_1111))); + Assert.AreEqual(maxmath.nextgreater((quarter)float.PositiveInfinity), (quarter)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((quarter)float.NegativeInfinity), (quarter)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater(quarter.MaxValue), (quarter)float.PositiveInfinity); + Assert.AreEqual(maxmath.asquarter((byte)1), maxmath.nextgreater(maxmath.asquarter((byte)0b1000_0000))); + Assert.AreEqual(maxmath.asquarter((byte)1), maxmath.nextgreater((quarter)0f)); + + for (int i = 0; i < 25; i++) + { + quarter f = (quarter)rng.NextFloat(quarter.MinValue / 2, quarter.MaxValue / 2); + + Assert.Greater((float)maxmath.nextgreater(f), (float)f); + } + } + + [Test] + public static void _quarter2() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextgreater((quarter2)maxmath.asquarter((byte)0b0111_1111)).x); + Assert.IsNaN(maxmath.nextgreater((quarter2)maxmath.asquarter((byte)0b0111_1111)).y); + Assert.AreEqual(maxmath.nextgreater((quarter2)(quarter)float.PositiveInfinity), (quarter2)(quarter)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((quarter2)(quarter)float.NegativeInfinity), (quarter2)(quarter)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater((quarter2)quarter.MaxValue), (quarter2)(quarter)float.PositiveInfinity); + Assert.AreEqual((quarter2)maxmath.asquarter((byte)1), maxmath.nextgreater((quarter2)maxmath.asquarter((byte)0b1000_0000))); + Assert.AreEqual((quarter2)maxmath.asquarter((byte)1), maxmath.nextgreater((quarter2)(quarter)0f)); + + for (int i = 0; i < 25; i++) + { + quarter2 f = (quarter2)rng.NextFloat2(quarter.MinValue / 2, quarter.MaxValue / 2); + + Assert.Greater((float)maxmath.nextgreater(f).x, (float)f.x); + Assert.Greater((float)maxmath.nextgreater(f).y, (float)f.y); + } + } + + [Test] + public static void _quarter3() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextgreater((quarter3)maxmath.asquarter((byte)0b0111_1111)).x); + Assert.IsNaN(maxmath.nextgreater((quarter3)maxmath.asquarter((byte)0b0111_1111)).y); + Assert.IsNaN(maxmath.nextgreater((quarter3)maxmath.asquarter((byte)0b0111_1111)).z); + Assert.AreEqual(maxmath.nextgreater((quarter3)(quarter)float.PositiveInfinity), (quarter3)(quarter)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((quarter3)(quarter)float.NegativeInfinity), (quarter3)(quarter)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater((quarter3)quarter.MaxValue), (quarter3)(quarter)float.PositiveInfinity); + Assert.AreEqual((quarter3)maxmath.asquarter((byte)1), maxmath.nextgreater((quarter3)maxmath.asquarter((byte)0b1000_0000))); + Assert.AreEqual((quarter3)maxmath.asquarter((byte)1), maxmath.nextgreater((quarter3)(quarter)0f)); + + for (int i = 0; i < 25; i++) + { + quarter3 f = (quarter3)rng.NextFloat3(quarter.MinValue / 2, quarter.MaxValue / 2); + + Assert.Greater((float)maxmath.nextgreater(f).x, (float)f.x); + Assert.Greater((float)maxmath.nextgreater(f).y, (float)f.y); + Assert.Greater((float)maxmath.nextgreater(f).z, (float)f.z); + } + } + + [Test] + public static void _quarter4() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextgreater((quarter4)maxmath.asquarter((byte)0b0111_1111)).x); + Assert.IsNaN(maxmath.nextgreater((quarter4)maxmath.asquarter((byte)0b0111_1111)).y); + Assert.IsNaN(maxmath.nextgreater((quarter4)maxmath.asquarter((byte)0b0111_1111)).z); + Assert.IsNaN(maxmath.nextgreater((quarter4)maxmath.asquarter((byte)0b0111_1111)).w); + Assert.AreEqual(maxmath.nextgreater((quarter4)(quarter)float.PositiveInfinity), (quarter4)(quarter)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((quarter4)(quarter)float.NegativeInfinity), (quarter4)(quarter)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater((quarter4)quarter.MaxValue), (quarter4)(quarter)float.PositiveInfinity); + Assert.AreEqual((quarter4)maxmath.asquarter((byte)1), maxmath.nextgreater((quarter4)maxmath.asquarter((byte)0b1000_0000))); + Assert.AreEqual((quarter4)maxmath.asquarter((byte)1), maxmath.nextgreater((quarter4)(quarter)0f)); + + for (int i = 0; i < 25; i++) + { + quarter4 f = (quarter4)rng.NextFloat4(quarter.MinValue / 2, quarter.MaxValue / 2); + + Assert.Greater((float)maxmath.nextgreater(f).x, (float)f.x); + Assert.Greater((float)maxmath.nextgreater(f).y, (float)f.y); + Assert.Greater((float)maxmath.nextgreater(f).z, (float)f.z); + Assert.Greater((float)maxmath.nextgreater(f).w, (float)f.w); + } + } + + [Test] + public static void _quarter8() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextgreater((quarter8)maxmath.asquarter((byte)0b0111_1111)).x0); + Assert.IsNaN(maxmath.nextgreater((quarter8)maxmath.asquarter((byte)0b0111_1111)).x1); + Assert.IsNaN(maxmath.nextgreater((quarter8)maxmath.asquarter((byte)0b0111_1111)).x2); + Assert.IsNaN(maxmath.nextgreater((quarter8)maxmath.asquarter((byte)0b0111_1111)).x3); + Assert.IsNaN(maxmath.nextgreater((quarter8)maxmath.asquarter((byte)0b0111_1111)).x4); + Assert.IsNaN(maxmath.nextgreater((quarter8)maxmath.asquarter((byte)0b0111_1111)).x5); + Assert.IsNaN(maxmath.nextgreater((quarter8)maxmath.asquarter((byte)0b0111_1111)).x6); + Assert.IsNaN(maxmath.nextgreater((quarter8)maxmath.asquarter((byte)0b0111_1111)).x7); + Assert.AreEqual(maxmath.nextgreater((quarter8)(quarter)float.PositiveInfinity), (quarter8)(quarter)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((quarter8)(quarter)float.NegativeInfinity), (quarter8)(quarter)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater((quarter8)quarter.MaxValue), (quarter8)(quarter)float.PositiveInfinity); + Assert.AreEqual((quarter8)maxmath.asquarter((byte)1), maxmath.nextgreater((quarter8)maxmath.asquarter((byte)0b1000_0000))); + Assert.AreEqual((quarter8)maxmath.asquarter((byte)1), maxmath.nextgreater((quarter8)(quarter)0f)); + + for (int i = 0; i < 25; i++) + { + quarter8 f = (quarter8)rng.NextFloat8(quarter.MinValue / 2, quarter.MaxValue / 2); + + Assert.Greater((float)maxmath.nextgreater(f).x0, (float)f.x0); + Assert.Greater((float)maxmath.nextgreater(f).x1, (float)f.x1); + Assert.Greater((float)maxmath.nextgreater(f).x2, (float)f.x2); + Assert.Greater((float)maxmath.nextgreater(f).x3, (float)f.x3); + Assert.Greater((float)maxmath.nextgreater(f).x4, (float)f.x4); + Assert.Greater((float)maxmath.nextgreater(f).x5, (float)f.x5); + Assert.Greater((float)maxmath.nextgreater(f).x6, (float)f.x6); + Assert.Greater((float)maxmath.nextgreater(f).x7, (float)f.x7); + } + } + + + [Test] + public static void _half() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextgreater(maxmath.ashalf((ushort)0x7FFF))); + Assert.AreEqual(maxmath.nextgreater((half)float.PositiveInfinity), (half)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((half)float.NegativeInfinity), (half)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater(half.MaxValueAsHalf), (half)float.PositiveInfinity); + Assert.AreEqual(maxmath.ashalf((ushort)1), maxmath.nextgreater(maxmath.ashalf((ushort)0x8000))); + Assert.AreEqual(maxmath.ashalf((ushort)1), maxmath.nextgreater((half)0f)); + + for (int i = 0; i < 25; i++) + { + half f = (half)rng.NextFloat(half.MinValueAsHalf / 2, half.MaxValueAsHalf / 2); + + Assert.Greater(maxmath.nextgreater(f), f); + } + } + + [Test] + public static void _half2() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextgreater((half2)maxmath.ashalf((ushort)0x7FFF)).x); + Assert.IsNaN(maxmath.nextgreater((half2)maxmath.ashalf((ushort)0x7FFF)).y); + Assert.AreEqual(maxmath.nextgreater((half2)(half)float.PositiveInfinity), (half2)(half)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((half2)(half)float.NegativeInfinity), (half2)(half)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater((half2)half.MaxValueAsHalf), (half2)(half)float.PositiveInfinity); + Assert.AreEqual((half2)maxmath.ashalf((ushort)1), maxmath.nextgreater((half2)maxmath.ashalf((ushort)0x8000))); + Assert.AreEqual((half2)maxmath.ashalf((ushort)1), maxmath.nextgreater((half2)(half)0f)); + + for (int i = 0; i < 25; i++) + { + half2 f = (half2)rng.NextFloat2(half.MinValueAsHalf / 2, half.MaxValueAsHalf / 2); + + Assert.Greater(maxmath.nextgreater(f).x, f.x); + Assert.Greater(maxmath.nextgreater(f).y, f.y); + } + } + + [Test] + public static void _half3() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextgreater((half3)maxmath.ashalf((ushort)0x7FFF)).x); + Assert.IsNaN(maxmath.nextgreater((half3)maxmath.ashalf((ushort)0x7FFF)).y); + Assert.IsNaN(maxmath.nextgreater((half3)maxmath.ashalf((ushort)0x7FFF)).z); + Assert.AreEqual(maxmath.nextgreater((half3)(half)float.PositiveInfinity), (half3)(half)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((half3)(half)float.NegativeInfinity), (half3)(half)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater((half3)half.MaxValueAsHalf), (half3)(half)float.PositiveInfinity); + Assert.AreEqual((half3)maxmath.ashalf((ushort)1), maxmath.nextgreater((half3)maxmath.ashalf((ushort)0x8000))); + Assert.AreEqual((half3)maxmath.ashalf((ushort)1), maxmath.nextgreater((half3)(half)0f)); + + for (int i = 0; i < 25; i++) + { + half3 f = (half3)rng.NextFloat3(half.MinValueAsHalf / 2, half.MaxValueAsHalf / 2); + + Assert.Greater(maxmath.nextgreater(f).x, f.x); + Assert.Greater(maxmath.nextgreater(f).y, f.y); + Assert.Greater(maxmath.nextgreater(f).z, f.z); + } + } + + [Test] + public static void _half4() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextgreater((half4)maxmath.ashalf((ushort)0x7FFF)).x); + Assert.IsNaN(maxmath.nextgreater((half4)maxmath.ashalf((ushort)0x7FFF)).y); + Assert.IsNaN(maxmath.nextgreater((half4)maxmath.ashalf((ushort)0x7FFF)).z); + Assert.IsNaN(maxmath.nextgreater((half4)maxmath.ashalf((ushort)0x7FFF)).w); + Assert.AreEqual(maxmath.nextgreater((half4)(half)float.PositiveInfinity), (half4)(half)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((half4)(half)float.NegativeInfinity), (half4)(half)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater((half4)half.MaxValueAsHalf), (half4)(half)float.PositiveInfinity); + Assert.AreEqual((half4)maxmath.ashalf((ushort)1), maxmath.nextgreater((half4)maxmath.ashalf((ushort)0x8000))); + Assert.AreEqual((half4)maxmath.ashalf((ushort)1), maxmath.nextgreater((half4)(half)0f)); + + for (int i = 0; i < 25; i++) + { + half4 f = (half4)rng.NextFloat4(half.MinValueAsHalf / 2, half.MaxValueAsHalf / 2); + + Assert.Greater(maxmath.nextgreater(f).x, f.x); + Assert.Greater(maxmath.nextgreater(f).y, f.y); + Assert.Greater(maxmath.nextgreater(f).z, f.z); + Assert.Greater(maxmath.nextgreater(f).w, f.w); + } + } + + [Test] + public static void _half8() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextgreater((half8)maxmath.ashalf((ushort)0x7FFF)).x0); + Assert.IsNaN(maxmath.nextgreater((half8)maxmath.ashalf((ushort)0x7FFF)).x1); + Assert.IsNaN(maxmath.nextgreater((half8)maxmath.ashalf((ushort)0x7FFF)).x2); + Assert.IsNaN(maxmath.nextgreater((half8)maxmath.ashalf((ushort)0x7FFF)).x3); + Assert.IsNaN(maxmath.nextgreater((half8)maxmath.ashalf((ushort)0x7FFF)).x4); + Assert.IsNaN(maxmath.nextgreater((half8)maxmath.ashalf((ushort)0x7FFF)).x5); + Assert.IsNaN(maxmath.nextgreater((half8)maxmath.ashalf((ushort)0x7FFF)).x6); + Assert.IsNaN(maxmath.nextgreater((half8)maxmath.ashalf((ushort)0x7FFF)).x7); + Assert.AreEqual(maxmath.nextgreater((half8)(half)float.PositiveInfinity), (half8)(half)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((half8)(half)float.NegativeInfinity), (half8)(half)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater((half8)half.MaxValueAsHalf), (half8)(half)float.PositiveInfinity); + Assert.AreEqual((half8)maxmath.ashalf((ushort)1), maxmath.nextgreater((half8)maxmath.ashalf((ushort)0x8000))); + Assert.AreEqual((half8)maxmath.ashalf((ushort)1), maxmath.nextgreater((half8)(half)0f)); + + for (int i = 0; i < 25; i++) + { + half8 f = (half8)rng.NextFloat8(half.MinValueAsHalf / 2, half.MaxValueAsHalf / 2); + + Assert.Greater(maxmath.nextgreater(f).x0, f.x0); + Assert.Greater(maxmath.nextgreater(f).x1, f.x1); + Assert.Greater(maxmath.nextgreater(f).x2, f.x2); + Assert.Greater(maxmath.nextgreater(f).x3, f.x3); + Assert.Greater(maxmath.nextgreater(f).x4, f.x4); + Assert.Greater(maxmath.nextgreater(f).x5, f.x5); + Assert.Greater(maxmath.nextgreater(f).x6, f.x6); + Assert.Greater(maxmath.nextgreater(f).x7, f.x7); + } + } + + + [Test] + public static void _float() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextgreater(math.asfloat(0x7FFF_FFFF))); + Assert.AreEqual(maxmath.nextgreater(float.PositiveInfinity), float.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater(float.NegativeInfinity), float.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater(float.MaxValue), float.PositiveInfinity); + Assert.AreEqual(float.Epsilon, maxmath.nextgreater(math.asfloat(0x8000_0000))); + Assert.AreEqual(float.Epsilon, maxmath.nextgreater(0f)); + + for (int i = 0; i < 25; i++) + { + float f = rng.NextFloat(float.MinValue / 2, float.MaxValue / 2); + + Assert.Greater(maxmath.nextgreater(f), f); + } + } + + [Test] + public static void _float2() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextgreater((float2)math.asfloat(0x7FFF_FFFF)).x); + Assert.IsNaN(maxmath.nextgreater((float2)math.asfloat(0x7FFF_FFFF)).y); + Assert.AreEqual(maxmath.nextgreater((float2)float.PositiveInfinity), (float2)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((float2)float.NegativeInfinity), (float2)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater((float2)float.MaxValue), (float2)float.PositiveInfinity); + Assert.AreEqual((float2)float.Epsilon, maxmath.nextgreater((float2)math.asfloat(0x8000_0000))); + Assert.AreEqual((float2)float.Epsilon, maxmath.nextgreater((float2)0f)); + + for (int i = 0; i < 25; i++) + { + float2 f = rng.NextFloat2(float.MinValue / 2, float.MaxValue / 2); + + Assert.Greater(maxmath.nextgreater(f).x, f.x); + Assert.Greater(maxmath.nextgreater(f).y, f.y); + } + } + + [Test] + public static void _float3() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextgreater((float3)math.asfloat(0x7FFF_FFFF)).x); + Assert.IsNaN(maxmath.nextgreater((float3)math.asfloat(0x7FFF_FFFF)).y); + Assert.IsNaN(maxmath.nextgreater((float3)math.asfloat(0x7FFF_FFFF)).z); + Assert.AreEqual(maxmath.nextgreater((float3)float.PositiveInfinity), (float3)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((float3)float.NegativeInfinity), (float3)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater((float3)float.MaxValue), (float3)float.PositiveInfinity); + Assert.AreEqual((float3)float.Epsilon, maxmath.nextgreater((float3)math.asfloat(0x8000_0000))); + Assert.AreEqual((float3)float.Epsilon, maxmath.nextgreater((float3)0f)); + + for (int i = 0; i < 25; i++) + { + float3 f = rng.NextFloat3(float.MinValue / 2, float.MaxValue / 2); + + Assert.Greater(maxmath.nextgreater(f).x, f.x); + Assert.Greater(maxmath.nextgreater(f).y, f.y); + Assert.Greater(maxmath.nextgreater(f).z, f.z); + } + } + + [Test] + public static void _float4() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextgreater((float4)math.asfloat(0x7FFF_FFFF)).x); + Assert.IsNaN(maxmath.nextgreater((float4)math.asfloat(0x7FFF_FFFF)).y); + Assert.IsNaN(maxmath.nextgreater((float4)math.asfloat(0x7FFF_FFFF)).z); + Assert.IsNaN(maxmath.nextgreater((float4)math.asfloat(0x7FFF_FFFF)).w); + Assert.AreEqual(maxmath.nextgreater((float4)float.PositiveInfinity), (float4)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((float4)float.NegativeInfinity), (float4)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater((float4)float.MaxValue), (float4)float.PositiveInfinity); + Assert.AreEqual((float4)float.Epsilon, maxmath.nextgreater((float4)math.asfloat(0x8000_0000))); + Assert.AreEqual((float4)float.Epsilon, maxmath.nextgreater((float4)0f)); + + for (int i = 0; i < 25; i++) + { + float4 f = rng.NextFloat4(float.MinValue / 2, float.MaxValue / 2); + + Assert.Greater(maxmath.nextgreater(f).x, f.x); + Assert.Greater(maxmath.nextgreater(f).y, f.y); + Assert.Greater(maxmath.nextgreater(f).z, f.z); + Assert.Greater(maxmath.nextgreater(f).w, f.w); + } + } + + [Test] + public static void _float8() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextgreater((float8)math.asfloat(0x7FFF_FFFF)).x0); + Assert.IsNaN(maxmath.nextgreater((float8)math.asfloat(0x7FFF_FFFF)).x1); + Assert.IsNaN(maxmath.nextgreater((float8)math.asfloat(0x7FFF_FFFF)).x2); + Assert.IsNaN(maxmath.nextgreater((float8)math.asfloat(0x7FFF_FFFF)).x3); + Assert.IsNaN(maxmath.nextgreater((float8)math.asfloat(0x7FFF_FFFF)).x4); + Assert.IsNaN(maxmath.nextgreater((float8)math.asfloat(0x7FFF_FFFF)).x5); + Assert.IsNaN(maxmath.nextgreater((float8)math.asfloat(0x7FFF_FFFF)).x6); + Assert.IsNaN(maxmath.nextgreater((float8)math.asfloat(0x7FFF_FFFF)).x7); + Assert.AreEqual(maxmath.nextgreater((float8)float.PositiveInfinity), (float8)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((float8)float.NegativeInfinity), (float8)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater((float8)float.MaxValue), (float8)float.PositiveInfinity); + Assert.AreEqual((float8)float.Epsilon, maxmath.nextgreater((float8)math.asfloat(0x8000_0000))); + Assert.AreEqual((float8)float.Epsilon, maxmath.nextgreater((float8)0f)); + + for (int i = 0; i < 25; i++) + { + float8 f = rng.NextFloat8(float.MinValue / 2, float.MaxValue / 2); + + Assert.Greater(maxmath.nextgreater(f).x0, f.x0); + Assert.Greater(maxmath.nextgreater(f).x1, f.x1); + Assert.Greater(maxmath.nextgreater(f).x2, f.x2); + Assert.Greater(maxmath.nextgreater(f).x3, f.x3); + Assert.Greater(maxmath.nextgreater(f).x4, f.x4); + Assert.Greater(maxmath.nextgreater(f).x5, f.x5); + Assert.Greater(maxmath.nextgreater(f).x6, f.x6); + Assert.Greater(maxmath.nextgreater(f).x7, f.x7); + } + } + + + [Test] + public static void _double() + { + Random64 rng = Random64.New; + + Assert.IsNaN(maxmath.nextgreater(math.asdouble(0x7FFF_FFFF_FFFF_FFFF))); + Assert.AreEqual(maxmath.nextgreater(double.PositiveInfinity), double.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater(double.NegativeInfinity), double.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater(double.MaxValue), double.PositiveInfinity); + Assert.AreEqual(double.Epsilon, maxmath.nextgreater(math.asdouble(0x8000_0000_0000_0000ul))); + Assert.AreEqual(double.Epsilon, maxmath.nextgreater(0d)); + + for (int i = 0; i < 25; i++) + { + double f = rng.NextDouble(double.MinValue / 2, double.MaxValue / 2); + + Assert.Greater(maxmath.nextgreater(f), f); + } + } + + [Test] + public static void _double2() + { + Random64 rng = Random64.New; + + Assert.IsNaN(maxmath.nextgreater((double2)math.asdouble(0x7FFF_FFFF_FFFF_FFFF)).x); + Assert.IsNaN(maxmath.nextgreater((double2)math.asdouble(0x7FFF_FFFF_FFFF_FFFF)).y); + Assert.AreEqual(maxmath.nextgreater((double2)double.PositiveInfinity), (double2)double.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((double2)double.NegativeInfinity), (double2)double.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater((double2)double.MaxValue), (double2)double.PositiveInfinity); + Assert.AreEqual((double2)double.Epsilon, maxmath.nextgreater((double2)math.asdouble(0x8000_0000_0000_0000ul))); + Assert.AreEqual((double2)double.Epsilon, maxmath.nextgreater((double2)0d)); + + for (int i = 0; i < 25; i++) + { + double2 f = rng.NextDouble2(double.MinValue / 2, double.MaxValue / 2); + + Assert.Greater(maxmath.nextgreater(f).x, f.x); + Assert.Greater(maxmath.nextgreater(f).y, f.y); + } + } + + [Test] + public static void _double3() + { + Random64 rng = Random64.New; + + Assert.IsNaN(maxmath.nextgreater((double3)math.asdouble(0x7FFF_FFFF_FFFF_FFFF)).x); + Assert.IsNaN(maxmath.nextgreater((double3)math.asdouble(0x7FFF_FFFF_FFFF_FFFF)).y); + Assert.IsNaN(maxmath.nextgreater((double3)math.asdouble(0x7FFF_FFFF_FFFF_FFFF)).z); + Assert.AreEqual(maxmath.nextgreater((double3)double.PositiveInfinity), (double3)double.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((double3)double.NegativeInfinity), (double3)double.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater((double3)double.MaxValue), (double3)double.PositiveInfinity); + Assert.AreEqual((double3)double.Epsilon, maxmath.nextgreater((double3)math.asdouble(0x8000_0000_0000_0000ul))); + Assert.AreEqual((double3)double.Epsilon, maxmath.nextgreater((double3)0d)); + + for (int i = 0; i < 25; i++) + { + double3 f = rng.NextDouble3(double.MinValue / 2, double.MaxValue / 2); + + Assert.Greater(maxmath.nextgreater(f).x, f.x); + Assert.Greater(maxmath.nextgreater(f).y, f.y); + Assert.Greater(maxmath.nextgreater(f).z, f.z); + } + } + + [Test] + public static void _double4() + { + Random64 rng = Random64.New; + + Assert.IsNaN(maxmath.nextgreater((double4)math.asdouble(0x7FFF_FFFF_FFFF_FFFF)).x); + Assert.IsNaN(maxmath.nextgreater((double4)math.asdouble(0x7FFF_FFFF_FFFF_FFFF)).y); + Assert.IsNaN(maxmath.nextgreater((double4)math.asdouble(0x7FFF_FFFF_FFFF_FFFF)).z); + Assert.IsNaN(maxmath.nextgreater((double4)math.asdouble(0x7FFF_FFFF_FFFF_FFFF)).w); + Assert.AreEqual(maxmath.nextgreater((double4)double.PositiveInfinity), (double4)double.PositiveInfinity); + Assert.AreEqual(maxmath.nextgreater((double4)double.NegativeInfinity), (double4)double.NegativeInfinity); + Assert.AreEqual(maxmath.nextgreater((double4)double.MaxValue), (double4)double.PositiveInfinity); + Assert.AreEqual((double4)double.Epsilon, maxmath.nextgreater((double4)math.asdouble(0x8000_0000_0000_0000ul))); + Assert.AreEqual((double4)double.Epsilon, maxmath.nextgreater((double4)0d)); + + for (int i = 0; i < 25; i++) + { + double4 f = rng.NextDouble4(double.MinValue / 2, double.MaxValue / 2); + + Assert.Greater(maxmath.nextgreater(f).x, f.x); + Assert.Greater(maxmath.nextgreater(f).y, f.y); + Assert.Greater(maxmath.nextgreater(f).z, f.z); + Assert.Greater(maxmath.nextgreater(f).w, f.w); + } + } + } +} diff --git a/Tests/Editor/Functions/Arithmetic/nextgreater.cs.meta b/Tests/Editor/Functions/Arithmetic/nextgreater.cs.meta new file mode 100644 index 0000000..f37a3b8 --- /dev/null +++ b/Tests/Editor/Functions/Arithmetic/nextgreater.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0da3c8a7a85553540a90be802af93008 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Editor/Functions/Arithmetic/nextsmaller.cs b/Tests/Editor/Functions/Arithmetic/nextsmaller.cs new file mode 100644 index 0000000..7648b14 --- /dev/null +++ b/Tests/Editor/Functions/Arithmetic/nextsmaller.cs @@ -0,0 +1,1181 @@ +using NUnit.Framework; +using Unity.Mathematics; + +namespace MaxMath.Tests +{ + public static class nextsmaller + { + [Test] + public static void _uint128() + { + Random128 rng = Random128.New; + + Assert.AreEqual(UInt128.MinValue, maxmath.nextsmaller(UInt128.MinValue)); + + for (int i = 0; i < 5; i++) + { + UInt128 t = rng.NextUInt128(); + + Assert.AreEqual(t == UInt128.MinValue ? UInt128.MinValue : t - 1, maxmath.nextsmaller(t)); + } + } + + + [Test] + public static void _int128() + { + Random128 rng = Random128.New; + + Assert.AreEqual(Int128.MinValue, maxmath.nextsmaller(Int128.MinValue)); + + for (int i = 0; i < 5; i++) + { + Int128 t = rng.NextInt128(); + + Assert.AreEqual(t == Int128.MinValue ? Int128.MinValue : t - 1, maxmath.nextsmaller(t)); + } + } + + + [Test] + public static void _byte() + { + Random8 rng = Random8.New; + + Assert.AreEqual(byte.MinValue, maxmath.nextsmaller(byte.MinValue)); + + for (int i = 0; i < 5; i++) + { + byte t = rng.NextByte(); + + Assert.AreEqual(t == byte.MinValue ? byte.MinValue : (byte)(t - 1), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _byte2() + { + Random8 rng = Random8.New; + + Assert.AreEqual((byte2)byte.MinValue, maxmath.nextsmaller((byte2)byte.MinValue)); + + for (int i = 0; i < 5; i++) + { + byte2 t = rng.NextByte2(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == byte.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _byte3() + { + Random8 rng = Random8.New; + + Assert.AreEqual((byte3)byte.MinValue, maxmath.nextsmaller((byte3)byte.MinValue)); + + for (int i = 0; i < 5; i++) + { + byte3 t = rng.NextByte3(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == byte.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _byte4() + { + Random8 rng = Random8.New; + + Assert.AreEqual((byte4)byte.MinValue, maxmath.nextsmaller((byte4)byte.MinValue)); + + for (int i = 0; i < 5; i++) + { + byte4 t = rng.NextByte4(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == byte.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _byte8() + { + Random8 rng = Random8.New; + + Assert.AreEqual((byte8)byte.MinValue, maxmath.nextsmaller((byte8)byte.MinValue)); + + for (int i = 0; i < 5; i++) + { + byte8 t = rng.NextByte8(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == byte.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _byte16() + { + Random8 rng = Random8.New; + + Assert.AreEqual((byte16)byte.MinValue, maxmath.nextsmaller((byte16)byte.MinValue)); + + for (int i = 0; i < 5; i++) + { + byte16 t = rng.NextByte16(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == byte.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _byte32() + { + Random8 rng = Random8.New; + + Assert.AreEqual((byte32)byte.MinValue, maxmath.nextsmaller((byte32)byte.MinValue)); + + for (int i = 0; i < 5; i++) + { + byte32 t = rng.NextByte32(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == byte.MinValue), maxmath.nextsmaller(t)); + } + } + + + [Test] + public static void _sbyte() + { + Random8 rng = Random8.New; + + Assert.AreEqual(sbyte.MinValue, maxmath.nextsmaller(sbyte.MinValue)); + + for (int i = 0; i < 5; i++) + { + sbyte t = rng.NextSByte(); + + Assert.AreEqual(t == sbyte.MinValue ? sbyte.MinValue : (sbyte)(t - 1), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _sbyte2() + { + Random8 rng = Random8.New; + + Assert.AreEqual((sbyte2)sbyte.MinValue, maxmath.nextsmaller((sbyte2)sbyte.MinValue)); + + for (int i = 0; i < 5; i++) + { + sbyte2 t = rng.NextSByte2(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == sbyte.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _sbyte3() + { + Random8 rng = Random8.New; + + Assert.AreEqual((sbyte3)sbyte.MinValue, maxmath.nextsmaller((sbyte3)sbyte.MinValue)); + + for (int i = 0; i < 5; i++) + { + sbyte3 t = rng.NextSByte3(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == sbyte.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _sbyte4() + { + Random8 rng = Random8.New; + + Assert.AreEqual((sbyte4)sbyte.MinValue, maxmath.nextsmaller((sbyte4)sbyte.MinValue)); + + for (int i = 0; i < 5; i++) + { + sbyte4 t = rng.NextSByte4(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == sbyte.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _sbyte8() + { + Random8 rng = Random8.New; + + Assert.AreEqual((sbyte8)sbyte.MinValue, maxmath.nextsmaller((sbyte8)sbyte.MinValue)); + + for (int i = 0; i < 5; i++) + { + sbyte8 t = rng.NextSByte8(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == sbyte.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _sbyte16() + { + Random8 rng = Random8.New; + + Assert.AreEqual((sbyte16)sbyte.MinValue, maxmath.nextsmaller((sbyte16)sbyte.MinValue)); + + for (int i = 0; i < 5; i++) + { + sbyte16 t = rng.NextSByte16(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == sbyte.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _sbyte32() + { + Random8 rng = Random8.New; + + Assert.AreEqual((sbyte32)sbyte.MinValue, maxmath.nextsmaller((sbyte32)sbyte.MinValue)); + + for (int i = 0; i < 5; i++) + { + sbyte32 t = rng.NextSByte32(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == sbyte.MinValue), maxmath.nextsmaller(t)); + } + } + + + [Test] + public static void _ushort() + { + Random16 rng = Random16.New; + + Assert.AreEqual(ushort.MinValue, maxmath.nextsmaller(ushort.MinValue)); + + for (int i = 0; i < 5; i++) + { + ushort t = rng.NextUShort(); + + Assert.AreEqual(t == ushort.MinValue ? ushort.MinValue : (ushort)(t - 1), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _ushort2() + { + Random16 rng = Random16.New; + + Assert.AreEqual((ushort2)ushort.MinValue, maxmath.nextsmaller((ushort2)ushort.MinValue)); + + for (int i = 0; i < 5; i++) + { + ushort2 t = rng.NextUShort2(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == ushort.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _ushort3() + { + Random16 rng = Random16.New; + + Assert.AreEqual((ushort3)ushort.MinValue, maxmath.nextsmaller((ushort3)ushort.MinValue)); + + for (int i = 0; i < 5; i++) + { + ushort3 t = rng.NextUShort3(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == ushort.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _ushort4() + { + Random16 rng = Random16.New; + + Assert.AreEqual((ushort4)ushort.MinValue, maxmath.nextsmaller((ushort4)ushort.MinValue)); + + for (int i = 0; i < 5; i++) + { + ushort4 t = rng.NextUShort4(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == ushort.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _ushort8() + { + Random16 rng = Random16.New; + + Assert.AreEqual((ushort8)ushort.MinValue, maxmath.nextsmaller((ushort8)ushort.MinValue)); + + for (int i = 0; i < 5; i++) + { + ushort8 t = rng.NextUShort8(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == ushort.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _ushort16() + { + Random16 rng = Random16.New; + + Assert.AreEqual((ushort16)ushort.MinValue, maxmath.nextsmaller((ushort16)ushort.MinValue)); + + for (int i = 0; i < 5; i++) + { + ushort16 t = rng.NextUShort16(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == ushort.MinValue), maxmath.nextsmaller(t)); + } + } + + + [Test] + public static void _short() + { + Random16 rng = Random16.New; + + Assert.AreEqual(short.MinValue, maxmath.nextsmaller(short.MinValue)); + + for (int i = 0; i < 5; i++) + { + short t = rng.NextShort(); + + Assert.AreEqual(t == short.MinValue ? short.MinValue : (short)(t - 1), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _short2() + { + Random16 rng = Random16.New; + + Assert.AreEqual((short2)short.MinValue, maxmath.nextsmaller((short2)short.MinValue)); + + for (int i = 0; i < 5; i++) + { + short2 t = rng.NextShort2(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == short.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _short3() + { + Random16 rng = Random16.New; + + Assert.AreEqual((short3)short.MinValue, maxmath.nextsmaller((short3)short.MinValue)); + + for (int i = 0; i < 5; i++) + { + short3 t = rng.NextShort3(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == short.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _short4() + { + Random16 rng = Random16.New; + + Assert.AreEqual((short4)short.MinValue, maxmath.nextsmaller((short4)short.MinValue)); + + for (int i = 0; i < 5; i++) + { + short4 t = rng.NextShort4(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == short.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _short8() + { + Random16 rng = Random16.New; + + Assert.AreEqual((short8)short.MinValue, maxmath.nextsmaller((short8)short.MinValue)); + + for (int i = 0; i < 5; i++) + { + short8 t = rng.NextShort8(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == short.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _short16() + { + Random16 rng = Random16.New; + + Assert.AreEqual((short16)short.MinValue, maxmath.nextsmaller((short16)short.MinValue)); + + for (int i = 0; i < 5; i++) + { + short16 t = rng.NextShort16(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == short.MinValue), maxmath.nextsmaller(t)); + } + } + + + [Test] + public static void _uint() + { + Random32 rng = Random32.New; + + Assert.AreEqual(uint.MinValue, maxmath.nextsmaller(uint.MinValue)); + + for (int i = 0; i < 5; i++) + { + uint t = rng.NextUInt(); + + Assert.AreEqual(t == uint.MinValue ? uint.MinValue : (uint)(t - 1), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _uint2() + { + Random32 rng = Random32.New; + + Assert.AreEqual((uint2)uint.MinValue, maxmath.nextsmaller((uint2)uint.MinValue)); + + for (int i = 0; i < 5; i++) + { + uint2 t = rng.NextUInt2(); + + Assert.AreEqual(math.select(t - 1, t, t == uint.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _uint3() + { + Random32 rng = Random32.New; + + Assert.AreEqual((uint3)uint.MinValue, maxmath.nextsmaller((uint3)uint.MinValue)); + + for (int i = 0; i < 5; i++) + { + uint3 t = rng.NextUInt3(); + + Assert.AreEqual(math.select(t - 1, t, t == uint.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _uint4() + { + Random32 rng = Random32.New; + + Assert.AreEqual((uint4)uint.MinValue, maxmath.nextsmaller((uint4)uint.MinValue)); + + for (int i = 0; i < 5; i++) + { + uint4 t = rng.NextUInt4(); + + Assert.AreEqual(math.select(t - 1, t, t == uint.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _uint8() + { + Random32 rng = Random32.New; + + Assert.AreEqual((uint8)uint.MinValue, maxmath.nextsmaller((uint8)uint.MinValue)); + + for (int i = 0; i < 5; i++) + { + uint8 t = rng.NextUInt8(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == uint.MinValue), maxmath.nextsmaller(t)); + } + } + + + [Test] + public static void _int() + { + Random32 rng = Random32.New; + + Assert.AreEqual(int.MinValue, maxmath.nextsmaller(int.MinValue)); + + for (int i = 0; i < 5; i++) + { + int t = rng.NextInt(); + + Assert.AreEqual(t == int.MinValue ? int.MinValue : (int)(t - 1), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _int2() + { + Random32 rng = Random32.New; + + Assert.AreEqual((int2)int.MinValue, maxmath.nextsmaller((int2)int.MinValue)); + + for (int i = 0; i < 5; i++) + { + int2 t = rng.NextInt2(); + + Assert.AreEqual(math.select(t - 1, t, t == int.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _int3() + { + Random32 rng = Random32.New; + + Assert.AreEqual((int3)int.MinValue, maxmath.nextsmaller((int3)int.MinValue)); + + for (int i = 0; i < 5; i++) + { + int3 t = rng.NextInt3(); + + Assert.AreEqual(math.select(t - 1, t, t == int.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _int4() + { + Random32 rng = Random32.New; + + Assert.AreEqual((int4)int.MinValue, maxmath.nextsmaller((int4)int.MinValue)); + + for (int i = 0; i < 5; i++) + { + int4 t = rng.NextInt4(); + + Assert.AreEqual(math.select(t - 1, t, t == int.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _int8() + { + Random32 rng = Random32.New; + + Assert.AreEqual((int8)int.MinValue, maxmath.nextsmaller((int8)int.MinValue)); + + for (int i = 0; i < 5; i++) + { + int8 t = rng.NextInt8(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == int.MinValue), maxmath.nextsmaller(t)); + } + } + + + [Test] + public static void _ulong() + { + Random64 rng = Random64.New; + + Assert.AreEqual(ulong.MinValue, maxmath.nextsmaller(ulong.MinValue)); + + for (int i = 0; i < 5; i++) + { + ulong t = rng.NextULong(); + + Assert.AreEqual(t == ulong.MinValue ? ulong.MinValue : (ulong)(t - 1), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _ulong2() + { + Random64 rng = Random64.New; + + Assert.AreEqual((ulong2)ulong.MinValue, maxmath.nextsmaller((ulong2)ulong.MinValue)); + + for (int i = 0; i < 5; i++) + { + ulong2 t = rng.NextULong2(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == ulong.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _ulong3() + { + Random64 rng = Random64.New; + + Assert.AreEqual((ulong3)ulong.MinValue, maxmath.nextsmaller((ulong3)ulong.MinValue)); + + for (int i = 0; i < 5; i++) + { + ulong3 t = rng.NextULong3(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == ulong.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _ulong4() + { + Random64 rng = Random64.New; + + Assert.AreEqual((ulong4)ulong.MinValue, maxmath.nextsmaller((ulong4)ulong.MinValue)); + + for (int i = 0; i < 5; i++) + { + ulong4 t = rng.NextULong4(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == ulong.MinValue), maxmath.nextsmaller(t)); + } + } + + + [Test] + public static void _long() + { + Random64 rng = Random64.New; + + Assert.AreEqual(long.MinValue, maxmath.nextsmaller(long.MinValue)); + + for (int i = 0; i < 5; i++) + { + long t = rng.NextLong(); + + Assert.AreEqual(t == long.MinValue ? long.MinValue : (long)(t - 1), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _long2() + { + Random64 rng = Random64.New; + + Assert.AreEqual((long2)long.MinValue, maxmath.nextsmaller((long2)long.MinValue)); + + for (int i = 0; i < 5; i++) + { + long2 t = rng.NextLong2(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == long.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _long3() + { + Random64 rng = Random64.New; + + Assert.AreEqual((long3)long.MinValue, maxmath.nextsmaller((long3)long.MinValue)); + + for (int i = 0; i < 5; i++) + { + long3 t = rng.NextLong3(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == long.MinValue), maxmath.nextsmaller(t)); + } + } + + [Test] + public static void _long4() + { + Random64 rng = Random64.New; + + Assert.AreEqual((long4)long.MinValue, maxmath.nextsmaller((long4)long.MinValue)); + + for (int i = 0; i < 5; i++) + { + long4 t = rng.NextLong4(); + + Assert.AreEqual(maxmath.select(t - 1, t, t == long.MinValue), maxmath.nextsmaller(t)); + } + } + + + [Test] + public static void _quarter() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextsmaller(quarter.NaN)); + Assert.AreEqual(maxmath.nextsmaller((quarter)float.PositiveInfinity), (quarter)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((quarter)float.NegativeInfinity), (quarter)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller(quarter.MinValue), (quarter)float.NegativeInfinity); + Assert.AreEqual(maxmath.asquarter((byte)0b1000_0001), maxmath.nextsmaller(maxmath.asquarter((byte)0b1000_0000))); + Assert.AreEqual(maxmath.asquarter((byte)0b1000_0001), maxmath.nextsmaller((quarter)0f)); + + for (int i = 0; i < 25; i++) + { + quarter f = (quarter)rng.NextFloat(quarter.MinValue / 2, quarter.MaxValue / 2); + + Assert.Less((float)maxmath.nextsmaller(f), (float)f); + } + } + + [Test] + public static void _quarter2() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextsmaller((quarter2)quarter.NaN).x); + Assert.IsNaN(maxmath.nextsmaller((quarter2)quarter.NaN).y); + Assert.AreEqual(maxmath.nextsmaller((quarter2)(quarter)float.PositiveInfinity), (quarter2)(quarter)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((quarter2)(quarter)float.NegativeInfinity), (quarter2)(quarter)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller((quarter2)quarter.MinValue), (quarter2)(quarter)float.NegativeInfinity); + Assert.AreEqual((quarter2)maxmath.asquarter((byte)0b1000_0001), maxmath.nextsmaller((quarter2)maxmath.asquarter((byte)0b1000_0000))); + Assert.AreEqual((quarter2)maxmath.asquarter((byte)0b1000_0001), maxmath.nextsmaller((quarter2)(quarter)0f)); + + for (int i = 0; i < 25; i++) + { + quarter2 f = (quarter2)rng.NextFloat2(quarter.MinValue / 2, quarter.MaxValue / 2); + + Assert.Less((float)maxmath.nextsmaller(f).x, (float)f.x); + Assert.Less((float)maxmath.nextsmaller(f).y, (float)f.y); + } + } + + [Test] + public static void _quarter3() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextsmaller((quarter3)quarter.NaN).x); + Assert.IsNaN(maxmath.nextsmaller((quarter3)quarter.NaN).y); + Assert.IsNaN(maxmath.nextsmaller((quarter3)quarter.NaN).z); + Assert.AreEqual(maxmath.nextsmaller((quarter3)(quarter)float.PositiveInfinity), (quarter3)(quarter)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((quarter3)(quarter)float.NegativeInfinity), (quarter3)(quarter)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller((quarter3)quarter.MinValue), (quarter3)(quarter)float.NegativeInfinity); + Assert.AreEqual((quarter3)maxmath.asquarter((byte)0b1000_0001), maxmath.nextsmaller((quarter3)maxmath.asquarter((byte)0b1000_0000))); + Assert.AreEqual((quarter3)maxmath.asquarter((byte)0b1000_0001), maxmath.nextsmaller((quarter3)(quarter)0f)); + + for (int i = 0; i < 25; i++) + { + quarter3 f = (quarter3)rng.NextFloat3(quarter.MinValue / 2, quarter.MaxValue / 2); + + Assert.Less((float)maxmath.nextsmaller(f).x, (float)f.x); + Assert.Less((float)maxmath.nextsmaller(f).y, (float)f.y); + Assert.Less((float)maxmath.nextsmaller(f).z, (float)f.z); + } + } + + [Test] + public static void _quarter4() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextsmaller((quarter4)quarter.NaN).x); + Assert.IsNaN(maxmath.nextsmaller((quarter4)quarter.NaN).y); + Assert.IsNaN(maxmath.nextsmaller((quarter4)quarter.NaN).z); + Assert.IsNaN(maxmath.nextsmaller((quarter4)quarter.NaN).w); + Assert.AreEqual(maxmath.nextsmaller((quarter4)(quarter)float.PositiveInfinity), (quarter4)(quarter)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((quarter4)(quarter)float.NegativeInfinity), (quarter4)(quarter)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller((quarter4)quarter.MinValue), (quarter4)(quarter)float.NegativeInfinity); + Assert.AreEqual((quarter4)maxmath.asquarter((byte)0b1000_0001), maxmath.nextsmaller((quarter4)maxmath.asquarter((byte)0b1000_0000))); + Assert.AreEqual((quarter4)maxmath.asquarter((byte)0b1000_0001), maxmath.nextsmaller((quarter4)(quarter)0f)); + + for (int i = 0; i < 25; i++) + { + quarter4 f = (quarter4)rng.NextFloat4(quarter.MinValue / 2, quarter.MaxValue / 2); + + Assert.Less((float)maxmath.nextsmaller(f).x, (float)f.x); + Assert.Less((float)maxmath.nextsmaller(f).y, (float)f.y); + Assert.Less((float)maxmath.nextsmaller(f).z, (float)f.z); + Assert.Less((float)maxmath.nextsmaller(f).w, (float)f.w); + } + } + + [Test] + public static void _quarter8() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextsmaller((quarter8)quarter.NaN).x0); + Assert.IsNaN(maxmath.nextsmaller((quarter8)quarter.NaN).x1); + Assert.IsNaN(maxmath.nextsmaller((quarter8)quarter.NaN).x2); + Assert.IsNaN(maxmath.nextsmaller((quarter8)quarter.NaN).x3); + Assert.IsNaN(maxmath.nextsmaller((quarter8)quarter.NaN).x4); + Assert.IsNaN(maxmath.nextsmaller((quarter8)quarter.NaN).x5); + Assert.IsNaN(maxmath.nextsmaller((quarter8)quarter.NaN).x6); + Assert.IsNaN(maxmath.nextsmaller((quarter8)quarter.NaN).x7); + Assert.AreEqual(maxmath.nextsmaller((quarter8)(quarter)float.PositiveInfinity), (quarter8)(quarter)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((quarter8)(quarter)float.NegativeInfinity), (quarter8)(quarter)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller((quarter8)quarter.MinValue), (quarter8)(quarter)float.NegativeInfinity); + Assert.AreEqual((quarter8)maxmath.asquarter((byte)0b1000_0001), maxmath.nextsmaller((quarter8)maxmath.asquarter((byte)0b1000_0000))); + Assert.AreEqual((quarter8)maxmath.asquarter((byte)0b1000_0001), maxmath.nextsmaller((quarter8)(quarter)0f)); + + for (int i = 0; i < 25; i++) + { + quarter8 f = (quarter8)rng.NextFloat8(quarter.MinValue / 2, quarter.MaxValue / 2); + + Assert.Less((float)maxmath.nextsmaller(f).x0, (float)f.x0); + Assert.Less((float)maxmath.nextsmaller(f).x1, (float)f.x1); + Assert.Less((float)maxmath.nextsmaller(f).x2, (float)f.x2); + Assert.Less((float)maxmath.nextsmaller(f).x3, (float)f.x3); + Assert.Less((float)maxmath.nextsmaller(f).x4, (float)f.x4); + Assert.Less((float)maxmath.nextsmaller(f).x5, (float)f.x5); + Assert.Less((float)maxmath.nextsmaller(f).x6, (float)f.x6); + Assert.Less((float)maxmath.nextsmaller(f).x7, (float)f.x7); + } + } + + + [Test] + public static void _half() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextsmaller(maxmath.ashalf((ushort)0x7C01))); + Assert.AreEqual(maxmath.nextsmaller((half)float.PositiveInfinity), (half)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((half)float.NegativeInfinity), (half)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller(half.MinValueAsHalf), (half)float.NegativeInfinity); + Assert.AreEqual(maxmath.ashalf((ushort)0x8001), maxmath.nextsmaller(maxmath.ashalf((ushort)0x8000))); + Assert.AreEqual(maxmath.ashalf((ushort)0x8001), maxmath.nextsmaller((half)0f)); + + for (int i = 0; i < 25; i++) + { + half f = (half)rng.NextFloat(half.MinValueAsHalf / 2, half.MaxValueAsHalf / 2); + + Assert.Less(maxmath.nextsmaller(f), f); + } + } + + [Test] + public static void _half2() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextsmaller((half2)maxmath.ashalf((ushort)0x7C01)).x); + Assert.IsNaN(maxmath.nextsmaller((half2)maxmath.ashalf((ushort)0x7C01)).y); + Assert.AreEqual(maxmath.nextsmaller((half2)(half)float.PositiveInfinity), (half2)(half)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((half2)(half)float.NegativeInfinity), (half2)(half)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller((half2)half.MinValueAsHalf), (half2)(half)float.NegativeInfinity); + Assert.AreEqual((half2)maxmath.ashalf((ushort)0x8001), maxmath.nextsmaller((half2)maxmath.ashalf((ushort)0x8000))); + Assert.AreEqual((half2)maxmath.ashalf((ushort)0x8001), maxmath.nextsmaller((half2)(half)0f)); + + for (int i = 0; i < 25; i++) + { + half2 f = (half2)rng.NextFloat2(half.MinValueAsHalf / 2, half.MaxValueAsHalf / 2); + + Assert.Less(maxmath.nextsmaller(f).x, f.x); + Assert.Less(maxmath.nextsmaller(f).y, f.y); + } + } + + [Test] + public static void _half3() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextsmaller((half3)maxmath.ashalf((ushort)0x7C01)).x); + Assert.IsNaN(maxmath.nextsmaller((half3)maxmath.ashalf((ushort)0x7C01)).y); + Assert.IsNaN(maxmath.nextsmaller((half3)maxmath.ashalf((ushort)0x7C01)).z); + Assert.AreEqual(maxmath.nextsmaller((half3)(half)float.PositiveInfinity), (half3)(half)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((half3)(half)float.NegativeInfinity), (half3)(half)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller((half3)half.MinValueAsHalf), (half3)(half)float.NegativeInfinity); + Assert.AreEqual((half3)maxmath.ashalf((ushort)0x8001), maxmath.nextsmaller((half3)maxmath.ashalf((ushort)0x8000))); + Assert.AreEqual((half3)maxmath.ashalf((ushort)0x8001), maxmath.nextsmaller((half3)(half)0f)); + + for (int i = 0; i < 25; i++) + { + half3 f = (half3)rng.NextFloat3(half.MinValueAsHalf / 2, half.MaxValueAsHalf / 2); + + Assert.Less(maxmath.nextsmaller(f).x, f.x); + Assert.Less(maxmath.nextsmaller(f).y, f.y); + Assert.Less(maxmath.nextsmaller(f).z, f.z); + } + } + + [Test] + public static void _half4() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextsmaller((half4)maxmath.ashalf((ushort)0x7C01)).x); + Assert.IsNaN(maxmath.nextsmaller((half4)maxmath.ashalf((ushort)0x7C01)).y); + Assert.IsNaN(maxmath.nextsmaller((half4)maxmath.ashalf((ushort)0x7C01)).z); + Assert.IsNaN(maxmath.nextsmaller((half4)maxmath.ashalf((ushort)0x7C01)).w); + Assert.AreEqual(maxmath.nextsmaller((half4)(half)float.PositiveInfinity), (half4)(half)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((half4)(half)float.NegativeInfinity), (half4)(half)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller((half4)half.MinValueAsHalf), (half4)(half)float.NegativeInfinity); + Assert.AreEqual((half4)maxmath.ashalf((ushort)0x8001), maxmath.nextsmaller((half4)maxmath.ashalf((ushort)0x8000))); + Assert.AreEqual((half4)maxmath.ashalf((ushort)0x8001), maxmath.nextsmaller((half4)(half)0f)); + + for (int i = 0; i < 25; i++) + { + half4 f = (half4)rng.NextFloat4(half.MinValueAsHalf / 2, half.MaxValueAsHalf / 2); + + Assert.Less(maxmath.nextsmaller(f).x, f.x); + Assert.Less(maxmath.nextsmaller(f).y, f.y); + Assert.Less(maxmath.nextsmaller(f).z, f.z); + Assert.Less(maxmath.nextsmaller(f).w, f.w); + } + } + + [Test] + public static void _half8() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextsmaller((half8)maxmath.ashalf((ushort)0x7C01)).x0); + Assert.IsNaN(maxmath.nextsmaller((half8)maxmath.ashalf((ushort)0x7C01)).x1); + Assert.IsNaN(maxmath.nextsmaller((half8)maxmath.ashalf((ushort)0x7C01)).x2); + Assert.IsNaN(maxmath.nextsmaller((half8)maxmath.ashalf((ushort)0x7C01)).x3); + Assert.IsNaN(maxmath.nextsmaller((half8)maxmath.ashalf((ushort)0x7C01)).x4); + Assert.IsNaN(maxmath.nextsmaller((half8)maxmath.ashalf((ushort)0x7C01)).x5); + Assert.IsNaN(maxmath.nextsmaller((half8)maxmath.ashalf((ushort)0x7C01)).x6); + Assert.IsNaN(maxmath.nextsmaller((half8)maxmath.ashalf((ushort)0x7C01)).x7); + Assert.AreEqual(maxmath.nextsmaller((half8)(half)float.PositiveInfinity), (half8)(half)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((half8)(half)float.NegativeInfinity), (half8)(half)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller((half8)half.MinValueAsHalf), (half8)(half)float.NegativeInfinity); + Assert.AreEqual((half8)maxmath.ashalf((ushort)0x8001), maxmath.nextsmaller((half8)maxmath.ashalf((ushort)0x8000))); + Assert.AreEqual((half8)maxmath.ashalf((ushort)0x8001), maxmath.nextsmaller((half8)(half)0f)); + + for (int i = 0; i < 25; i++) + { + half8 f = (half8)rng.NextFloat8(half.MinValueAsHalf / 2, half.MaxValueAsHalf / 2); + + Assert.Less(maxmath.nextsmaller(f).x0, f.x0); + Assert.Less(maxmath.nextsmaller(f).x1, f.x1); + Assert.Less(maxmath.nextsmaller(f).x2, f.x2); + Assert.Less(maxmath.nextsmaller(f).x3, f.x3); + Assert.Less(maxmath.nextsmaller(f).x4, f.x4); + Assert.Less(maxmath.nextsmaller(f).x5, f.x5); + Assert.Less(maxmath.nextsmaller(f).x6, f.x6); + Assert.Less(maxmath.nextsmaller(f).x7, f.x7); + } + } + + + [Test] + public static void _float() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextsmaller(float.NaN)); + Assert.AreEqual(maxmath.nextsmaller(float.PositiveInfinity), float.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller(float.NegativeInfinity), float.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller(float.MinValue), float.NegativeInfinity); + Assert.AreEqual((-float.Epsilon), maxmath.nextsmaller(math.asfloat(0x8000_0000))); + Assert.AreEqual((-float.Epsilon), maxmath.nextsmaller(0f)); + + for (int i = 0; i < 25; i++) + { + float f = rng.NextFloat(float.MinValue / 2, float.MaxValue / 2); + + Assert.Less(maxmath.nextsmaller(f), f); + } + } + + [Test] + public static void _float2() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextsmaller((float2)float.NaN).x); + Assert.IsNaN(maxmath.nextsmaller((float2)float.NaN).y); + Assert.AreEqual(maxmath.nextsmaller((float2)float.PositiveInfinity), (float2)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((float2)float.NegativeInfinity), (float2)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller((float2)float.MinValue), (float2)float.NegativeInfinity); + Assert.AreEqual((float2)(-float.Epsilon), maxmath.nextsmaller((float2)math.asfloat(0x8000_0000))); + Assert.AreEqual((float2)(-float.Epsilon), maxmath.nextsmaller((float2)0f)); + + for (int i = 0; i < 25; i++) + { + float2 f = rng.NextFloat2(float.MinValue / 2, float.MaxValue / 2); + + Assert.Less(maxmath.nextsmaller(f).x, f.x); + Assert.Less(maxmath.nextsmaller(f).y, f.y); + } + } + + [Test] + public static void _float3() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextsmaller((float3)float.NaN).x); + Assert.IsNaN(maxmath.nextsmaller((float3)float.NaN).y); + Assert.IsNaN(maxmath.nextsmaller((float3)float.NaN).z); + Assert.AreEqual(maxmath.nextsmaller((float3)float.PositiveInfinity), (float3)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((float3)float.NegativeInfinity), (float3)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller((float3)float.MinValue), (float3)float.NegativeInfinity); + Assert.AreEqual((float3)(-float.Epsilon), maxmath.nextsmaller((float3)math.asfloat(0x8000_0000))); + Assert.AreEqual((float3)(-float.Epsilon), maxmath.nextsmaller((float3)0f)); + + for (int i = 0; i < 25; i++) + { + float3 f = rng.NextFloat3(float.MinValue / 2, float.MaxValue / 2); + + Assert.Less(maxmath.nextsmaller(f).x, f.x); + Assert.Less(maxmath.nextsmaller(f).y, f.y); + Assert.Less(maxmath.nextsmaller(f).z, f.z); + } + } + + [Test] + public static void _float4() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextsmaller((float4)float.NaN).x); + Assert.IsNaN(maxmath.nextsmaller((float4)float.NaN).y); + Assert.IsNaN(maxmath.nextsmaller((float4)float.NaN).z); + Assert.IsNaN(maxmath.nextsmaller((float4)float.NaN).w); + Assert.AreEqual(maxmath.nextsmaller((float4)float.PositiveInfinity), (float4)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((float4)float.NegativeInfinity), (float4)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller((float4)float.MinValue), (float4)float.NegativeInfinity); + Assert.AreEqual((float4)(-float.Epsilon), maxmath.nextsmaller((float4)math.asfloat(0x8000_0000))); + Assert.AreEqual((float4)(-float.Epsilon), maxmath.nextsmaller((float4)0f)); + + for (int i = 0; i < 25; i++) + { + float4 f = rng.NextFloat4(float.MinValue / 2, float.MaxValue / 2); + + Assert.Less(maxmath.nextsmaller(f).x, f.x); + Assert.Less(maxmath.nextsmaller(f).y, f.y); + Assert.Less(maxmath.nextsmaller(f).z, f.z); + Assert.Less(maxmath.nextsmaller(f).w, f.w); + } + } + + [Test] + public static void _float8() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nextsmaller((float8)float.NaN).x0); + Assert.IsNaN(maxmath.nextsmaller((float8)float.NaN).x1); + Assert.IsNaN(maxmath.nextsmaller((float8)float.NaN).x2); + Assert.IsNaN(maxmath.nextsmaller((float8)float.NaN).x3); + Assert.IsNaN(maxmath.nextsmaller((float8)float.NaN).x4); + Assert.IsNaN(maxmath.nextsmaller((float8)float.NaN).x5); + Assert.IsNaN(maxmath.nextsmaller((float8)float.NaN).x6); + Assert.IsNaN(maxmath.nextsmaller((float8)float.NaN).x7); + Assert.AreEqual(maxmath.nextsmaller((float8)float.PositiveInfinity), (float8)float.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((float8)float.NegativeInfinity), (float8)float.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller((float8)float.MinValue), (float8)float.NegativeInfinity); + Assert.AreEqual((float8)(-float.Epsilon), maxmath.nextsmaller((float8)math.asfloat(0x8000_0000))); + Assert.AreEqual((float8)(-float.Epsilon), maxmath.nextsmaller((float8)0f)); + + for (int i = 0; i < 25; i++) + { + float8 f = rng.NextFloat8(float.MinValue / 2, float.MaxValue / 2); + + Assert.Less(maxmath.nextsmaller(f).x0, f.x0); + Assert.Less(maxmath.nextsmaller(f).x1, f.x1); + Assert.Less(maxmath.nextsmaller(f).x2, f.x2); + Assert.Less(maxmath.nextsmaller(f).x3, f.x3); + Assert.Less(maxmath.nextsmaller(f).x4, f.x4); + Assert.Less(maxmath.nextsmaller(f).x5, f.x5); + Assert.Less(maxmath.nextsmaller(f).x6, f.x6); + Assert.Less(maxmath.nextsmaller(f).x7, f.x7); + } + } + + + [Test] + public static void _double() + { + Random64 rng = Random64.New; + + Assert.IsNaN(maxmath.nextsmaller(double.NaN)); + Assert.AreEqual(maxmath.nextsmaller(double.PositiveInfinity), double.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller(double.NegativeInfinity), double.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller(double.MinValue), double.NegativeInfinity); + Assert.AreEqual((-double.Epsilon), maxmath.nextsmaller(math.asdouble(0x8000_0000_0000_0000ul))); + Assert.AreEqual((-double.Epsilon), maxmath.nextsmaller(0d)); + + for (int i = 0; i < 25; i++) + { + double f = rng.NextDouble(double.MinValue / 2, double.MaxValue / 2); + + Assert.Less(maxmath.nextsmaller(f), f); + } + } + + [Test] + public static void _double2() + { + Random64 rng = Random64.New; + + Assert.IsNaN(maxmath.nextsmaller((double2)double.NaN).x); + Assert.IsNaN(maxmath.nextsmaller((double2)double.NaN).y); + Assert.AreEqual(maxmath.nextsmaller((double2)double.PositiveInfinity), (double2)double.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((double2)double.NegativeInfinity), (double2)double.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller((double2)double.MinValue), (double2)double.NegativeInfinity); + Assert.AreEqual((double2)(-double.Epsilon), maxmath.nextsmaller((double2)math.asdouble(0x8000_0000_0000_0000ul))); + Assert.AreEqual((double2)(-double.Epsilon), maxmath.nextsmaller((double2)0d)); + + for (int i = 0; i < 25; i++) + { + double2 f = rng.NextDouble2(double.MinValue / 2, double.MaxValue / 2); + + Assert.Less(maxmath.nextsmaller(f).x, f.x); + Assert.Less(maxmath.nextsmaller(f).y, f.y); + } + } + + [Test] + public static void _double3() + { + Random64 rng = Random64.New; + + Assert.IsNaN(maxmath.nextsmaller((double3)double.NaN).x); + Assert.IsNaN(maxmath.nextsmaller((double3)double.NaN).y); + Assert.IsNaN(maxmath.nextsmaller((double3)double.NaN).z); + Assert.AreEqual(maxmath.nextsmaller((double3)double.PositiveInfinity), (double3)double.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((double3)double.NegativeInfinity), (double3)double.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller((double3)double.MinValue), (double3)double.NegativeInfinity); + Assert.AreEqual((double3)(-double.Epsilon), maxmath.nextsmaller((double3)math.asdouble(0x8000_0000_0000_0000ul))); + Assert.AreEqual((double3)(-double.Epsilon), maxmath.nextsmaller((double3)0d)); + + for (int i = 0; i < 25; i++) + { + double3 f = rng.NextDouble3(double.MinValue / 2, double.MaxValue / 2); + + Assert.Less(maxmath.nextsmaller(f).x, f.x); + Assert.Less(maxmath.nextsmaller(f).y, f.y); + Assert.Less(maxmath.nextsmaller(f).z, f.z); + } + } + + [Test] + public static void _double4() + { + Random64 rng = Random64.New; + + Assert.IsNaN(maxmath.nextsmaller((double4)double.NaN).x); + Assert.IsNaN(maxmath.nextsmaller((double4)double.NaN).y); + Assert.IsNaN(maxmath.nextsmaller((double4)double.NaN).z); + Assert.IsNaN(maxmath.nextsmaller((double4)double.NaN).w); + Assert.AreEqual(maxmath.nextsmaller((double4)double.PositiveInfinity), (double4)double.PositiveInfinity); + Assert.AreEqual(maxmath.nextsmaller((double4)double.NegativeInfinity), (double4)double.NegativeInfinity); + Assert.AreEqual(maxmath.nextsmaller((double4)double.MinValue), (double4)double.NegativeInfinity); + Assert.AreEqual((double4)(-double.Epsilon), maxmath.nextsmaller((double4)math.asdouble(0x8000_0000_0000_0000ul))); + Assert.AreEqual((double4)(-double.Epsilon), maxmath.nextsmaller((double4)0d)); + + for (int i = 0; i < 25; i++) + { + double4 f = rng.NextDouble4(double.MinValue / 2, double.MaxValue / 2); + + Assert.Less(maxmath.nextsmaller(f).x, f.x); + Assert.Less(maxmath.nextsmaller(f).y, f.y); + Assert.Less(maxmath.nextsmaller(f).z, f.z); + Assert.Less(maxmath.nextsmaller(f).w, f.w); + } + } + } +} diff --git a/Tests/Editor/Functions/Arithmetic/nextsmaller.cs.meta b/Tests/Editor/Functions/Arithmetic/nextsmaller.cs.meta new file mode 100644 index 0000000..d8e7793 --- /dev/null +++ b/Tests/Editor/Functions/Arithmetic/nextsmaller.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b0cda9fd138db14498bb83f4aa27cfea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Editor/Functions/Arithmetic/nexttoward.cs b/Tests/Editor/Functions/Arithmetic/nexttoward.cs new file mode 100644 index 0000000..8fda5be --- /dev/null +++ b/Tests/Editor/Functions/Arithmetic/nexttoward.cs @@ -0,0 +1,1641 @@ +using NUnit.Framework; +using Unity.Mathematics; + +namespace MaxMath.Tests +{ + public static class nexttoward + { + [Test] + public static void _uint128() + { + Random128 rng = Random128.New; + + for (int i = 0; i < 25; i++) + { + UInt128 l = rng.NextUInt128(); + UInt128 r = rng.NextUInt128(); + + Assert.AreEqual(maxmath.nexttoward(l, r), l == r ? l : (l < r ? l + 1 : l - 1)); + } + } + + + [Test] + public static void _int128() + { + Random128 rng = Random128.New; + + for (int i = 0; i < 25; i++) + { + Int128 l = rng.NextInt128(); + Int128 r = rng.NextInt128(); + + Assert.AreEqual(maxmath.nexttoward(l, r), l == r ? l : (l < r ? l + 1 : l - 1)); + } + } + + + [Test] + public static void _byte() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + byte l = rng.NextByte(); + byte r = rng.NextByte(); + + Assert.AreEqual(maxmath.nexttoward(l, r), l == r ? l : (l < r ? l + 1 : l - 1)); + } + } + + [Test] + public static void _byte2() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + byte2 l = rng.NextByte2(); + byte2 r = rng.NextByte2(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _byte3() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + byte3 l = rng.NextByte3(); + byte3 r = rng.NextByte3(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _byte4() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + byte4 l = rng.NextByte4(); + byte4 r = rng.NextByte4(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _byte8() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + byte8 l = rng.NextByte8(); + byte8 r = rng.NextByte8(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _byte16() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + byte16 l = rng.NextByte16(); + byte16 r = rng.NextByte16(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _byte32() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + byte32 l = rng.NextByte32(); + byte32 r = rng.NextByte32(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + + [Test] + public static void _sbyte() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + sbyte l = rng.NextSByte(); + sbyte r = rng.NextSByte(); + + Assert.AreEqual(maxmath.nexttoward(l, r), l == r ? l : (l < r ? l + 1 : l - 1)); + } + } + + [Test] + public static void _sbyte2() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + sbyte2 l = rng.NextSByte2(); + sbyte2 r = rng.NextSByte2(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _sbyte3() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + sbyte3 l = rng.NextSByte3(); + sbyte3 r = rng.NextSByte3(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _sbyte4() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + sbyte4 l = rng.NextSByte4(); + sbyte4 r = rng.NextSByte4(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _sbyte8() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + sbyte8 l = rng.NextSByte8(); + sbyte8 r = rng.NextSByte8(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _sbyte16() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + sbyte16 l = rng.NextSByte16(); + sbyte16 r = rng.NextSByte16(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _sbyte32() + { + Random8 rng = Random8.New; + + for (int i = 0; i < 25; i++) + { + sbyte32 l = rng.NextSByte32(); + sbyte32 r = rng.NextSByte32(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + + [Test] + public static void _short() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + short l = rng.NextShort(); + short r = rng.NextShort(); + + Assert.AreEqual(maxmath.nexttoward(l, r), l == r ? l : (l < r ? l + 1 : l - 1)); + } + } + + [Test] + public static void _short2() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + short2 l = rng.NextShort2(); + short2 r = rng.NextShort2(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _short3() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + short3 l = rng.NextShort3(); + short3 r = rng.NextShort3(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _short4() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + short4 l = rng.NextShort4(); + short4 r = rng.NextShort4(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _short8() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + short8 l = rng.NextShort8(); + short8 r = rng.NextShort8(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _short16() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + short16 l = rng.NextShort16(); + short16 r = rng.NextShort16(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + + [Test] + public static void _ushort() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + ushort l = rng.NextUShort(); + ushort r = rng.NextUShort(); + + Assert.AreEqual(maxmath.nexttoward(l, r), l == r ? l : (l < r ? l + 1 : l - 1)); + } + } + + [Test] + public static void _ushort2() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + ushort2 l = rng.NextUShort2(); + ushort2 r = rng.NextUShort2(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _ushort3() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + ushort3 l = rng.NextUShort3(); + ushort3 r = rng.NextUShort3(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _ushort4() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + ushort4 l = rng.NextUShort4(); + ushort4 r = rng.NextUShort4(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _ushort8() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + ushort8 l = rng.NextUShort8(); + ushort8 r = rng.NextUShort8(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _ushort16() + { + Random16 rng = Random16.New; + + for (int i = 0; i < 25; i++) + { + ushort16 l = rng.NextUShort16(); + ushort16 r = rng.NextUShort16(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + + [Test] + public static void _int() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 25; i++) + { + int l = rng.NextInt(); + int r = rng.NextInt(); + + Assert.AreEqual(maxmath.nexttoward(l, r), l == r ? l : (l < r ? l + 1 : l - 1)); + } + } + + [Test] + public static void _int2() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 25; i++) + { + int2 l = rng.NextInt2(); + int2 r = rng.NextInt2(); + + Assert.AreEqual(maxmath.nexttoward(l, r), math.select(math.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _int3() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 25; i++) + { + int3 l = rng.NextInt3(); + int3 r = rng.NextInt3(); + + Assert.AreEqual(maxmath.nexttoward(l, r), math.select(math.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _int4() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 25; i++) + { + int4 l = rng.NextInt4(); + int4 r = rng.NextInt4(); + + Assert.AreEqual(maxmath.nexttoward(l, r), math.select(math.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _int8() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 25; i++) + { + int8 l = rng.NextInt8(); + int8 r = rng.NextInt8(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + + [Test] + public static void _uint() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 25; i++) + { + uint l = rng.NextUInt(); + uint r = rng.NextUInt(); + + Assert.AreEqual(maxmath.nexttoward(l, r), l == r ? l : (l < r ? l + 1 : l - 1)); + } + } + + [Test] + public static void _uint2() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 25; i++) + { + uint2 l = rng.NextUInt2(); + uint2 r = rng.NextUInt2(); + + Assert.AreEqual(maxmath.nexttoward(l, r), math.select(math.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _uint3() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 25; i++) + { + uint3 l = rng.NextUInt3(); + uint3 r = rng.NextUInt3(); + + Assert.AreEqual(maxmath.nexttoward(l, r), math.select(math.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _uint4() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 25; i++) + { + uint4 l = rng.NextUInt4(); + uint4 r = rng.NextUInt4(); + + Assert.AreEqual(maxmath.nexttoward(l, r), math.select(math.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _uint8() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 25; i++) + { + uint8 l = rng.NextUInt8(); + uint8 r = rng.NextUInt8(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + + [Test] + public static void _long() + { + Random64 rng = Random64.New; + + for (long i = 0; i < 25; i++) + { + long l = rng.NextLong(); + long r = rng.NextLong(); + + Assert.AreEqual(maxmath.nexttoward(l, r), l == r ? l : (l < r ? l + 1 : l - 1)); + } + } + + [Test] + public static void _long2() + { + Random64 rng = Random64.New; + + for (long i = 0; i < 25; i++) + { + long2 l = rng.NextLong2(); + long2 r = rng.NextLong2(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _long3() + { + Random64 rng = Random64.New; + + for (long i = 0; i < 25; i++) + { + long3 l = rng.NextLong3(); + long3 r = rng.NextLong3(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _long4() + { + Random64 rng = Random64.New; + + for (long i = 0; i < 25; i++) + { + long4 l = rng.NextLong4(); + long4 r = rng.NextLong4(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + + [Test] + public static void _ulong() + { + Random64 rng = Random64.New; + + for (long i = 0; i < 25; i++) + { + ulong l = rng.NextULong(); + ulong r = rng.NextULong(); + + Assert.AreEqual(maxmath.nexttoward(l, r), l == r ? l : (l < r ? l + 1 : l - 1)); + } + } + + [Test] + public static void _ulong2() + { + Random64 rng = Random64.New; + + for (long i = 0; i < 25; i++) + { + ulong2 l = rng.NextULong2(); + ulong2 r = rng.NextULong2(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _ulong3() + { + Random64 rng = Random64.New; + + for (long i = 0; i < 25; i++) + { + ulong3 l = rng.NextULong3(); + ulong3 r = rng.NextULong3(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + [Test] + public static void _ulong4() + { + Random64 rng = Random64.New; + + for (long i = 0; i < 25; i++) + { + ulong4 l = rng.NextULong4(); + ulong4 r = rng.NextULong4(); + + Assert.AreEqual(maxmath.nexttoward(l, r), maxmath.select(maxmath.select(l + 1, l - 1, l > r), l, l == r)); + } + } + + + [Test] + public static void _quarter() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nexttoward((quarter)rng.NextFloat(), (quarter)quarter.NaN)); + Assert.IsNaN(maxmath.nexttoward((quarter)quarter.NaN, (quarter)rng.NextFloat())); + Assert.IsNaN(maxmath.nexttoward((quarter)0f, (quarter)quarter.NaN)); + Assert.IsNaN(maxmath.nexttoward((quarter)quarter.NaN, (quarter)0f)); + Assert.IsNaN(maxmath.nexttoward((quarter)quarter.NaN, (quarter)quarter.NaN)); + + Assert.AreEqual(maxmath.nexttoward((quarter)quarter.NegativeInfinity, (quarter)quarter.NegativeInfinity), (quarter)quarter.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter)quarter.NegativeInfinity, (quarter)quarter.PositiveInfinity), (quarter)quarter.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter)quarter.PositiveInfinity, (quarter)quarter.NegativeInfinity), (quarter)quarter.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter)quarter.PositiveInfinity, (quarter)quarter.PositiveInfinity), (quarter)quarter.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((quarter)quarter.MinValue, (quarter)quarter.NegativeInfinity), (quarter)quarter.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter)quarter.MinValue, (quarter)quarter.PositiveInfinity), (quarter)maxmath.nextgreater(quarter.MinValue)); + Assert.AreEqual(maxmath.nexttoward((quarter)quarter.MaxValue, (quarter)quarter.NegativeInfinity), (quarter)maxmath.nextsmaller(quarter.MaxValue)); + Assert.AreEqual(maxmath.nexttoward((quarter)quarter.MaxValue, (quarter)quarter.PositiveInfinity), (quarter)quarter.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((quarter)0f, (quarter)quarter.PositiveInfinity), (quarter)quarter.Epsilon); + Assert.AreEqual(maxmath.nexttoward((quarter)0f, (quarter)quarter.NegativeInfinity), (quarter)(-quarter.Epsilon)); + Assert.AreEqual(maxmath.nexttoward((quarter)maxmath.asquarter(0x80), (quarter)quarter.PositiveInfinity), (quarter)quarter.Epsilon); + Assert.AreEqual(maxmath.nexttoward((quarter)maxmath.asquarter(0x80), (quarter)quarter.NegativeInfinity), (quarter)(-quarter.Epsilon)); + + for (int i = 0; i < 25; i++) + { + quarter from = (quarter)rng.NextFloat(quarter.MinValue, quarter.MaxValue); + quarter to = (quarter)rng.NextFloat(quarter.MinValue, quarter.MaxValue); + quarter next = maxmath.nexttoward(from, to); + + Assert.AreEqual(from, maxmath.nexttoward(from, from)); + + if (from < to) + { + Assert.AreEqual(maxmath.nextgreater(from), next); + } + else if (from > to) + { + Assert.AreEqual(maxmath.nextsmaller(from), next); + } + else + { + Assert.AreEqual(from, next); + } + } + } + + [Test] + public static void _quarter2() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nexttoward((quarter2)rng.NextFloat2(), (quarter2)quarter.NaN).x); + Assert.IsNaN(maxmath.nexttoward((quarter2)quarter.NaN, (quarter2)rng.NextFloat2()).x); + Assert.IsNaN(maxmath.nexttoward((quarter2)0f, (quarter2)quarter.NaN).x); + Assert.IsNaN(maxmath.nexttoward((quarter2)quarter.NaN, (quarter2)0f).x); + Assert.IsNaN(maxmath.nexttoward((quarter2)quarter.NaN, (quarter2)quarter.NaN).x); + + Assert.AreEqual(maxmath.nexttoward((quarter2)quarter.NegativeInfinity, (quarter2)quarter.NegativeInfinity), (quarter2)quarter.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter2)quarter.NegativeInfinity, (quarter2)quarter.PositiveInfinity), (quarter2)quarter.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter2)quarter.PositiveInfinity, (quarter2)quarter.NegativeInfinity), (quarter2)quarter.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter2)quarter.PositiveInfinity, (quarter2)quarter.PositiveInfinity), (quarter2)quarter.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((quarter2)quarter.MinValue, (quarter2)quarter.NegativeInfinity), (quarter2)quarter.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter2)quarter.MinValue, (quarter2)quarter.PositiveInfinity), (quarter2)maxmath.nextgreater(quarter.MinValue)); + Assert.AreEqual(maxmath.nexttoward((quarter2)quarter.MaxValue, (quarter2)quarter.NegativeInfinity), (quarter2)maxmath.nextsmaller(quarter.MaxValue)); + Assert.AreEqual(maxmath.nexttoward((quarter2)quarter.MaxValue, (quarter2)quarter.PositiveInfinity), (quarter2)quarter.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((quarter2)0f, (quarter2)quarter.PositiveInfinity), (quarter2)quarter.Epsilon); + Assert.AreEqual(maxmath.nexttoward((quarter2)0f, (quarter2)quarter.NegativeInfinity), (quarter2)(-quarter.Epsilon)); + Assert.AreEqual(maxmath.nexttoward((quarter2)maxmath.asquarter(0x80), (quarter2)quarter.PositiveInfinity), (quarter2)quarter.Epsilon); + Assert.AreEqual(maxmath.nexttoward((quarter2)maxmath.asquarter(0x80), (quarter2)quarter.NegativeInfinity), (quarter2)(-quarter.Epsilon)); + + for (int i = 0; i < 25; i++) + { + quarter2 from = (quarter2)rng.NextFloat2(quarter.MinValue, quarter.MaxValue); + quarter2 to = (quarter2)rng.NextFloat2(quarter.MinValue, quarter.MaxValue); + quarter2 next = maxmath.nexttoward(from, to); + + for (int j = 0; j < 2; j++) + { + Assert.AreEqual(from[j], maxmath.nexttoward(from, from)[j]); + + if (from[j] < to[j]) + { + Assert.AreEqual(maxmath.nextgreater(from)[j], next[j]); + } + else if (from[j] > to[j]) + { + Assert.AreEqual(maxmath.nextsmaller(from)[j], next[j]); + } + else + { + Assert.AreEqual(from[j], next[j]); + } + } + } + } + + [Test] + public static void _quarter3() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nexttoward((quarter3)rng.NextFloat3(), (quarter3)quarter.NaN).x); + Assert.IsNaN(maxmath.nexttoward((quarter3)quarter.NaN, (quarter3)rng.NextFloat3()).x); + Assert.IsNaN(maxmath.nexttoward((quarter3)0f, (quarter3)quarter.NaN).x); + Assert.IsNaN(maxmath.nexttoward((quarter3)quarter.NaN, (quarter3)0f).x); + Assert.IsNaN(maxmath.nexttoward((quarter3)quarter.NaN, (quarter3)quarter.NaN).x); + + Assert.AreEqual(maxmath.nexttoward((quarter3)quarter.NegativeInfinity, (quarter3)quarter.NegativeInfinity), (quarter3)quarter.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter3)quarter.NegativeInfinity, (quarter3)quarter.PositiveInfinity), (quarter3)quarter.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter3)quarter.PositiveInfinity, (quarter3)quarter.NegativeInfinity), (quarter3)quarter.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter3)quarter.PositiveInfinity, (quarter3)quarter.PositiveInfinity), (quarter3)quarter.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((quarter3)quarter.MinValue, (quarter3)quarter.NegativeInfinity), (quarter3)quarter.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter3)quarter.MinValue, (quarter3)quarter.PositiveInfinity), (quarter3)maxmath.nextgreater(quarter.MinValue)); + Assert.AreEqual(maxmath.nexttoward((quarter3)quarter.MaxValue, (quarter3)quarter.NegativeInfinity), (quarter3)maxmath.nextsmaller(quarter.MaxValue)); + Assert.AreEqual(maxmath.nexttoward((quarter3)quarter.MaxValue, (quarter3)quarter.PositiveInfinity), (quarter3)quarter.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((quarter3)0f, (quarter3)quarter.PositiveInfinity), (quarter3)quarter.Epsilon); + Assert.AreEqual(maxmath.nexttoward((quarter3)0f, (quarter3)quarter.NegativeInfinity), (quarter3)(-quarter.Epsilon)); + Assert.AreEqual(maxmath.nexttoward((quarter3)maxmath.asquarter(0x80), (quarter3)quarter.PositiveInfinity), (quarter3)quarter.Epsilon); + Assert.AreEqual(maxmath.nexttoward((quarter3)maxmath.asquarter(0x80), (quarter3)quarter.NegativeInfinity), (quarter3)(-quarter.Epsilon)); + + for (int i = 0; i < 25; i++) + { + quarter3 from = (quarter3)rng.NextFloat3(quarter.MinValue, quarter.MaxValue); + quarter3 to = (quarter3)rng.NextFloat3(quarter.MinValue, quarter.MaxValue); + quarter3 next = maxmath.nexttoward(from, to); + + for (int j = 0; j < 3; j++) + { + Assert.AreEqual(from[j], maxmath.nexttoward(from, from)[j]); + + if (from[j] < to[j]) + { + Assert.AreEqual(maxmath.nextgreater(from)[j], next[j]); + } + else if (from[j] > to[j]) + { + Assert.AreEqual(maxmath.nextsmaller(from)[j], next[j]); + } + else + { + Assert.AreEqual(from[j], next[j]); + } + } + } + } + + [Test] + public static void _quarter4() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nexttoward((quarter4)rng.NextFloat4(), (quarter4)quarter.NaN).x); + Assert.IsNaN(maxmath.nexttoward((quarter4)quarter.NaN, (quarter4)rng.NextFloat4()).x); + Assert.IsNaN(maxmath.nexttoward((quarter4)0f, (quarter4)quarter.NaN).x); + Assert.IsNaN(maxmath.nexttoward((quarter4)quarter.NaN, (quarter4)0f).x); + Assert.IsNaN(maxmath.nexttoward((quarter4)quarter.NaN, (quarter4)quarter.NaN).x); + + Assert.AreEqual(maxmath.nexttoward((quarter4)quarter.NegativeInfinity, (quarter4)quarter.NegativeInfinity), (quarter4)quarter.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter4)quarter.NegativeInfinity, (quarter4)quarter.PositiveInfinity), (quarter4)quarter.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter4)quarter.PositiveInfinity, (quarter4)quarter.NegativeInfinity), (quarter4)quarter.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter4)quarter.PositiveInfinity, (quarter4)quarter.PositiveInfinity), (quarter4)quarter.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((quarter4)quarter.MinValue, (quarter4)quarter.NegativeInfinity), (quarter4)quarter.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter4)quarter.MinValue, (quarter4)quarter.PositiveInfinity), (quarter4)maxmath.nextgreater(quarter.MinValue)); + Assert.AreEqual(maxmath.nexttoward((quarter4)quarter.MaxValue, (quarter4)quarter.NegativeInfinity), (quarter4)maxmath.nextsmaller(quarter.MaxValue)); + Assert.AreEqual(maxmath.nexttoward((quarter4)quarter.MaxValue, (quarter4)quarter.PositiveInfinity), (quarter4)quarter.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((quarter4)0f, (quarter4)quarter.PositiveInfinity), (quarter4)quarter.Epsilon); + Assert.AreEqual(maxmath.nexttoward((quarter4)0f, (quarter4)quarter.NegativeInfinity), (quarter4)(-quarter.Epsilon)); + Assert.AreEqual(maxmath.nexttoward((quarter4)maxmath.asquarter(0x80), (quarter4)quarter.PositiveInfinity), (quarter4)quarter.Epsilon); + Assert.AreEqual(maxmath.nexttoward((quarter4)maxmath.asquarter(0x80), (quarter4)quarter.NegativeInfinity), (quarter4)(-quarter.Epsilon)); + + for (int i = 0; i < 25; i++) + { + quarter4 from = (quarter4)rng.NextFloat4(quarter.MinValue, quarter.MaxValue); + quarter4 to = (quarter4)rng.NextFloat4(quarter.MinValue, quarter.MaxValue); + quarter4 next = maxmath.nexttoward(from, to); + + for (int j = 0; j < 4; j++) + { + Assert.AreEqual(from[j], maxmath.nexttoward(from, from)[j]); + + if (from[j] < to[j]) + { + Assert.AreEqual(maxmath.nextgreater(from)[j], next[j]); + } + else if (from[j] > to[j]) + { + Assert.AreEqual(maxmath.nextsmaller(from)[j], next[j]); + } + else + { + Assert.AreEqual(from[j], next[j]); + } + } + } + } + + [Test] + public static void _quarter8() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nexttoward((quarter8)rng.NextFloat8(), (quarter8)quarter.NaN).x0); + Assert.IsNaN(maxmath.nexttoward((quarter8)quarter.NaN, (quarter8)rng.NextFloat8()).x0); + Assert.IsNaN(maxmath.nexttoward((quarter8)0f, (quarter8)quarter.NaN).x0); + Assert.IsNaN(maxmath.nexttoward((quarter8)quarter.NaN, (quarter8)0f).x0); + Assert.IsNaN(maxmath.nexttoward((quarter8)quarter.NaN, (quarter8)quarter.NaN).x0); + + Assert.AreEqual(maxmath.nexttoward((quarter8)quarter.NegativeInfinity, (quarter8)quarter.NegativeInfinity), (quarter8)quarter.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter8)quarter.NegativeInfinity, (quarter8)quarter.PositiveInfinity), (quarter8)quarter.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter8)quarter.PositiveInfinity, (quarter8)quarter.NegativeInfinity), (quarter8)quarter.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter8)quarter.PositiveInfinity, (quarter8)quarter.PositiveInfinity), (quarter8)quarter.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((quarter8)quarter.MinValue, (quarter8)quarter.NegativeInfinity), (quarter8)quarter.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((quarter8)quarter.MinValue, (quarter8)quarter.PositiveInfinity), (quarter8)maxmath.nextgreater(quarter.MinValue)); + Assert.AreEqual(maxmath.nexttoward((quarter8)quarter.MaxValue, (quarter8)quarter.NegativeInfinity), (quarter8)maxmath.nextsmaller(quarter.MaxValue)); + Assert.AreEqual(maxmath.nexttoward((quarter8)quarter.MaxValue, (quarter8)quarter.PositiveInfinity), (quarter8)quarter.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((quarter8)0f, (quarter8)quarter.PositiveInfinity), (quarter8)quarter.Epsilon); + Assert.AreEqual(maxmath.nexttoward((quarter8)0f, (quarter8)quarter.NegativeInfinity), (quarter8)(-quarter.Epsilon)); + Assert.AreEqual(maxmath.nexttoward((quarter8)maxmath.asquarter(0x80), (quarter8)quarter.PositiveInfinity), (quarter8)quarter.Epsilon); + Assert.AreEqual(maxmath.nexttoward((quarter8)maxmath.asquarter(0x80), (quarter8)quarter.NegativeInfinity), (quarter8)(-quarter.Epsilon)); + + for (int i = 0; i < 25; i++) + { + quarter8 from = (quarter8)rng.NextFloat8(quarter.MinValue, quarter.MaxValue); + quarter8 to = (quarter8)rng.NextFloat8(quarter.MinValue, quarter.MaxValue); + quarter8 next = maxmath.nexttoward(from, to); + + for (int j = 0; j < 8; j++) + { + Assert.AreEqual(from[j], maxmath.nexttoward(from, from)[j]); + + if (from[j] < to[j]) + { + Assert.AreEqual(maxmath.nextgreater(from)[j], next[j]); + } + else if (from[j] > to[j]) + { + Assert.AreEqual(maxmath.nextsmaller(from)[j], next[j]); + } + else + { + Assert.AreEqual(from[j], next[j]); + } + } + } + } + + + [Test] + public static void _half() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nexttoward((half)rng.NextFloat(), (half)float.NaN)); + Assert.IsNaN(maxmath.nexttoward((half)float.NaN, (half)rng.NextFloat())); + Assert.IsNaN(maxmath.nexttoward((half)0f, (half)float.NaN)); + Assert.IsNaN(maxmath.nexttoward((half)float.NaN, (half)0f)); + Assert.IsNaN(maxmath.nexttoward((half)float.NaN, (half)float.NaN)); + + Assert.AreEqual(maxmath.nexttoward((half)float.NegativeInfinity, (half)float.NegativeInfinity), (half)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((half)float.NegativeInfinity, (half)float.PositiveInfinity), (half)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((half)float.PositiveInfinity, (half)float.NegativeInfinity), (half)float.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((half)float.PositiveInfinity, (half)float.PositiveInfinity), (half)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((half)half.MinValueAsHalf, (half)float.NegativeInfinity), (half)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((half)half.MinValueAsHalf, (half)float.PositiveInfinity), (half)maxmath.nextgreater(half.MinValueAsHalf)); + Assert.AreEqual(maxmath.nexttoward((half)half.MaxValueAsHalf, (half)float.NegativeInfinity), (half)maxmath.nextsmaller(half.MaxValueAsHalf)); + Assert.AreEqual(maxmath.nexttoward((half)half.MaxValueAsHalf, (half)float.PositiveInfinity), (half)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((half)0f, (half)float.PositiveInfinity), maxmath.ashalf((ushort)1)); + Assert.AreEqual(maxmath.nexttoward((half)0f, (half)float.NegativeInfinity), maxmath.ashalf((ushort)0x8001)); + Assert.AreEqual(maxmath.nexttoward((half)maxmath.ashalf((ushort)0x8000), (half)float.PositiveInfinity), maxmath.ashalf((ushort)1)); + Assert.AreEqual(maxmath.nexttoward((half)maxmath.ashalf((ushort)0x8000), (half)float.NegativeInfinity), maxmath.ashalf((ushort)0x8001)); + + for (int i = 0; i < 25; i++) + { + half from = (half)rng.NextFloat(half.MinValueAsHalf, half.MaxValueAsHalf); + half to = (half)rng.NextFloat(half.MinValueAsHalf, half.MaxValueAsHalf); + half next = maxmath.nexttoward(from, to); + + Assert.AreEqual(from, maxmath.nexttoward(from, from)); + + if (from < to) + { + Assert.AreEqual(maxmath.nextgreater(from), next); + } + else if (from > to) + { + Assert.AreEqual(maxmath.nextsmaller(from), next); + } + else + { + Assert.AreEqual(from, next); + } + } + } + + [Test] + public static void _half2() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nexttoward((half2)rng.NextFloat2(), (half2)float.NaN).x); + Assert.IsNaN(maxmath.nexttoward((half2)float.NaN, (half2)rng.NextFloat2()).x); + Assert.IsNaN(maxmath.nexttoward((half2)0f, (half2)float.NaN).x); + Assert.IsNaN(maxmath.nexttoward((half2)float.NaN, (half2)0f).x); + Assert.IsNaN(maxmath.nexttoward((half2)float.NaN, (half2)float.NaN).x); + + Assert.AreEqual(maxmath.nexttoward((half2)float.NegativeInfinity, (half2)float.NegativeInfinity), (half2)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((half2)float.NegativeInfinity, (half2)float.PositiveInfinity), (half2)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((half2)float.PositiveInfinity, (half2)float.NegativeInfinity), (half2)float.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((half2)float.PositiveInfinity, (half2)float.PositiveInfinity), (half2)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((half2)half.MinValueAsHalf, (half2)float.NegativeInfinity), (half2)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((half2)half.MinValueAsHalf, (half2)float.PositiveInfinity), (half2)maxmath.nextgreater(half.MinValueAsHalf)); + Assert.AreEqual(maxmath.nexttoward((half2)half.MaxValueAsHalf, (half2)float.NegativeInfinity), (half2)maxmath.nextsmaller(half.MaxValueAsHalf)); + Assert.AreEqual(maxmath.nexttoward((half2)half.MaxValueAsHalf, (half2)float.PositiveInfinity), (half2)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((half2)0f, (half2)float.PositiveInfinity), (half2)maxmath.ashalf((ushort)1)); + Assert.AreEqual(maxmath.nexttoward((half2)0f, (half2)float.NegativeInfinity), (half2)maxmath.ashalf((ushort)0x8001)); + Assert.AreEqual(maxmath.nexttoward((half2)maxmath.ashalf((ushort)0x8000), (half2)float.PositiveInfinity), (half2)maxmath.ashalf((ushort)1)); + Assert.AreEqual(maxmath.nexttoward((half2)maxmath.ashalf((ushort)0x8000), (half2)float.NegativeInfinity), (half2)maxmath.ashalf((ushort)0x8001)); + + for (int i = 0; i < 25; i++) + { + half2 from = (half2)rng.NextFloat2(half.MinValue, half.MaxValue); + half2 to = (half2)rng.NextFloat2(half.MinValue, half.MaxValue); + half2 next = maxmath.nexttoward(from, to); + + for (int j = 0; j < 2; j++) + { + Assert.AreEqual(from[j], maxmath.nexttoward(from, from)[j]); + + if (from[j] < to[j]) + { + Assert.AreEqual(maxmath.nextgreater(from)[j], next[j]); + } + else if (from[j] > to[j]) + { + Assert.AreEqual(maxmath.nextsmaller(from)[j], next[j]); + } + else + { + Assert.AreEqual(from[j], next[j]); + } + } + } + } + + [Test] + public static void _half3() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nexttoward((half3)rng.NextFloat3(), (half3)float.NaN).x); + Assert.IsNaN(maxmath.nexttoward((half3)float.NaN, (half3)rng.NextFloat3()).x); + Assert.IsNaN(maxmath.nexttoward((half3)0f, (half3)float.NaN).x); + Assert.IsNaN(maxmath.nexttoward((half3)float.NaN, (half3)0f).x); + Assert.IsNaN(maxmath.nexttoward((half3)float.NaN, (half3)float.NaN).x); + + Assert.AreEqual(maxmath.nexttoward((half3)float.NegativeInfinity, (half3)float.NegativeInfinity), (half3)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((half3)float.NegativeInfinity, (half3)float.PositiveInfinity), (half3)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((half3)float.PositiveInfinity, (half3)float.NegativeInfinity), (half3)float.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((half3)float.PositiveInfinity, (half3)float.PositiveInfinity), (half3)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((half3)half.MinValueAsHalf, (half3)float.NegativeInfinity), (half3)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((half3)half.MinValueAsHalf, (half3)float.PositiveInfinity), (half3)maxmath.nextgreater(half.MinValueAsHalf)); + Assert.AreEqual(maxmath.nexttoward((half3)half.MaxValueAsHalf, (half3)float.NegativeInfinity), (half3)maxmath.nextsmaller(half.MaxValueAsHalf)); + Assert.AreEqual(maxmath.nexttoward((half3)half.MaxValueAsHalf, (half3)float.PositiveInfinity), (half3)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((half3)0f, (half3)float.PositiveInfinity), (half3)maxmath.ashalf((ushort)1)); + Assert.AreEqual(maxmath.nexttoward((half3)0f, (half3)float.NegativeInfinity), (half3)maxmath.ashalf((ushort)0x8001)); + Assert.AreEqual(maxmath.nexttoward((half3)maxmath.ashalf((ushort)0x8000), (half3)float.PositiveInfinity), (half3)maxmath.ashalf((ushort)1)); + Assert.AreEqual(maxmath.nexttoward((half3)maxmath.ashalf((ushort)0x8000), (half3)float.NegativeInfinity), (half3)maxmath.ashalf((ushort)0x8001)); + + for (int i = 0; i < 25; i++) + { + half3 from = (half3)rng.NextFloat3(half.MinValue, half.MaxValue); + half3 to = (half3)rng.NextFloat3(half.MinValue, half.MaxValue); + half3 next = maxmath.nexttoward(from, to); + + for (int j = 0; j < 3; j++) + { + Assert.AreEqual(from[j], maxmath.nexttoward(from, from)[j]); + + if (from[j] < to[j]) + { + Assert.AreEqual(maxmath.nextgreater(from)[j], next[j]); + } + else if (from[j] > to[j]) + { + Assert.AreEqual(maxmath.nextsmaller(from)[j], next[j]); + } + else + { + Assert.AreEqual(from[j], next[j]); + } + } + } + } + + [Test] + public static void _half4() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nexttoward((half4)rng.NextFloat4(), (half4)float.NaN).x); + Assert.IsNaN(maxmath.nexttoward((half4)float.NaN, (half4)rng.NextFloat4()).x); + Assert.IsNaN(maxmath.nexttoward((half4)0f, (half4)float.NaN).x); + Assert.IsNaN(maxmath.nexttoward((half4)float.NaN, (half4)0f).x); + Assert.IsNaN(maxmath.nexttoward((half4)float.NaN, (half4)float.NaN).x); + + Assert.AreEqual(maxmath.nexttoward((half4)float.NegativeInfinity, (half4)float.NegativeInfinity), (half4)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((half4)float.NegativeInfinity, (half4)float.PositiveInfinity), (half4)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((half4)float.PositiveInfinity, (half4)float.NegativeInfinity), (half4)float.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((half4)float.PositiveInfinity, (half4)float.PositiveInfinity), (half4)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((half4)half.MinValueAsHalf, (half4)float.NegativeInfinity), (half4)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((half4)half.MinValueAsHalf, (half4)float.PositiveInfinity), (half4)maxmath.nextgreater(half.MinValueAsHalf)); + Assert.AreEqual(maxmath.nexttoward((half4)half.MaxValueAsHalf, (half4)float.NegativeInfinity), (half4)maxmath.nextsmaller(half.MaxValueAsHalf)); + Assert.AreEqual(maxmath.nexttoward((half4)half.MaxValueAsHalf, (half4)float.PositiveInfinity), (half4)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((half4)0f, (half4)float.PositiveInfinity), (half4)maxmath.ashalf((ushort)1)); + Assert.AreEqual(maxmath.nexttoward((half4)0f, (half4)float.NegativeInfinity), (half4)maxmath.ashalf((ushort)0x8001)); + Assert.AreEqual(maxmath.nexttoward((half4)maxmath.ashalf((ushort)0x8000), (half4)float.PositiveInfinity), (half4)maxmath.ashalf((ushort)1)); + Assert.AreEqual(maxmath.nexttoward((half4)maxmath.ashalf((ushort)0x8000), (half4)float.NegativeInfinity), (half4)maxmath.ashalf((ushort)0x8001)); + + for (int i = 0; i < 25; i++) + { + half4 from = (half4)rng.NextFloat4(half.MinValue, half.MaxValue); + half4 to = (half4)rng.NextFloat4(half.MinValue, half.MaxValue); + half4 next = maxmath.nexttoward(from, to); + + for (int j = 0; j < 4; j++) + { + Assert.AreEqual(from[j], maxmath.nexttoward(from, from)[j]); + + if (from[j] < to[j]) + { + Assert.AreEqual(maxmath.nextgreater(from)[j], next[j]); + } + else if (from[j] > to[j]) + { + Assert.AreEqual(maxmath.nextsmaller(from)[j], next[j]); + } + else + { + Assert.AreEqual(from[j], next[j]); + } + } + } + } + + [Test] + public static void _half8() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nexttoward((half8)rng.NextFloat8(), (half8)float.NaN).x0); + Assert.IsNaN(maxmath.nexttoward((half8)float.NaN, (half8)rng.NextFloat8()).x0); + Assert.IsNaN(maxmath.nexttoward((half8)0f, (half8)float.NaN).x0); + Assert.IsNaN(maxmath.nexttoward((half8)float.NaN, (half8)0f).x0); + Assert.IsNaN(maxmath.nexttoward((half8)float.NaN, (half8)float.NaN).x0); + + Assert.AreEqual(maxmath.nexttoward((half8)float.NegativeInfinity, (half8)float.NegativeInfinity), (half8)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((half8)float.NegativeInfinity, (half8)float.PositiveInfinity), (half8)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((half8)float.PositiveInfinity, (half8)float.NegativeInfinity), (half8)float.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((half8)float.PositiveInfinity, (half8)float.PositiveInfinity), (half8)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((half8)half.MinValueAsHalf, (half8)float.NegativeInfinity), (half8)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((half8)half.MinValueAsHalf, (half8)float.PositiveInfinity), (half8)maxmath.nextgreater(half.MinValueAsHalf)); + Assert.AreEqual(maxmath.nexttoward((half8)half.MaxValueAsHalf, (half8)float.NegativeInfinity), (half8)maxmath.nextsmaller(half.MaxValueAsHalf)); + Assert.AreEqual(maxmath.nexttoward((half8)half.MaxValueAsHalf, (half8)float.PositiveInfinity), (half8)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((half8)0f, (half8)float.PositiveInfinity), (half8)maxmath.ashalf((ushort)1)); + Assert.AreEqual(maxmath.nexttoward((half8)0f, (half8)float.NegativeInfinity), (half8)maxmath.ashalf((ushort)0x8001)); + Assert.AreEqual(maxmath.nexttoward((half8)maxmath.ashalf((ushort)0x8000), (half8)float.PositiveInfinity), (half8)maxmath.ashalf((ushort)1)); + Assert.AreEqual(maxmath.nexttoward((half8)maxmath.ashalf((ushort)0x8000), (half8)float.NegativeInfinity), (half8)maxmath.ashalf((ushort)0x8001)); + + for (int i = 0; i < 25; i++) + { + half8 from = (half8)rng.NextFloat8(half.MinValue, half.MaxValue); + half8 to = (half8)rng.NextFloat8(half.MinValue, half.MaxValue); + half8 next = maxmath.nexttoward(from, to); + + for (int j = 0; j < 8; j++) + { + Assert.AreEqual(from[j], maxmath.nexttoward(from, from)[j]); + + if (from[j] < to[j]) + { + Assert.AreEqual(maxmath.nextgreater(from)[j], next[j]); + } + else if (from[j] > to[j]) + { + Assert.AreEqual(maxmath.nextsmaller(from)[j], next[j]); + } + else + { + Assert.AreEqual(from[j], next[j]); + } + } + } + } + + + [Test] + public static void _float() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nexttoward(rng.NextFloat(), float.NaN)); + Assert.IsNaN(maxmath.nexttoward(float.NaN, rng.NextFloat())); + Assert.IsNaN(maxmath.nexttoward(0f, float.NaN)); + Assert.IsNaN(maxmath.nexttoward(float.NaN, 0f)); + Assert.IsNaN(maxmath.nexttoward(float.NaN, float.NaN)); + + Assert.AreEqual(maxmath.nexttoward(float.NegativeInfinity, float.NegativeInfinity), float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward(float.NegativeInfinity, float.PositiveInfinity), float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward(float.PositiveInfinity, float.NegativeInfinity), float.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward(float.PositiveInfinity, float.PositiveInfinity), float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward(float.MinValue, float.NegativeInfinity), float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward(float.MinValue, float.PositiveInfinity), maxmath.nextgreater(float.MinValue)); + Assert.AreEqual(maxmath.nexttoward(float.MaxValue, float.NegativeInfinity), maxmath.nextsmaller(float.MaxValue)); + Assert.AreEqual(maxmath.nexttoward(float.MaxValue, float.PositiveInfinity), float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward(0f, float.PositiveInfinity), float.Epsilon); + Assert.AreEqual(maxmath.nexttoward(0f, float.NegativeInfinity), -float.Epsilon); + Assert.AreEqual(maxmath.nexttoward(math.asfloat(0x8000_0000), float.PositiveInfinity), float.Epsilon); + Assert.AreEqual(maxmath.nexttoward(math.asfloat(0x8000_0000), float.NegativeInfinity), -float.Epsilon); + + for (int i = 0; i < 25; i++) + { + float from = rng.NextFloat(float.MinValue / 2, float.MaxValue / 2); + float to = rng.NextFloat(float.MinValue / 2, float.MaxValue / 2); + float next = maxmath.nexttoward(from, to); + + Assert.AreEqual(from, maxmath.nexttoward(from, from)); + + if (from < to) + { + Assert.AreEqual(maxmath.nextgreater(from), next); + } + else if (from > to) + { + Assert.AreEqual(maxmath.nextsmaller(from), next); + } + else + { + Assert.AreEqual(from, next); + } + } + } + + [Test] + public static void _float2() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nexttoward(rng.NextFloat2(), (float2)float.NaN).x); + Assert.IsNaN(maxmath.nexttoward((float2)float.NaN, rng.NextFloat2()).x); + Assert.IsNaN(maxmath.nexttoward((float2)0f, (float2)float.NaN).x); + Assert.IsNaN(maxmath.nexttoward((float2)float.NaN, (float2)0f).x); + Assert.IsNaN(maxmath.nexttoward((float2)float.NaN, (float2)float.NaN).x); + + Assert.AreEqual(maxmath.nexttoward((float2)float.NegativeInfinity, (float2)float.NegativeInfinity), (float2)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((float2)float.NegativeInfinity, (float2)float.PositiveInfinity), (float2)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((float2)float.PositiveInfinity, (float2)float.NegativeInfinity), (float2)float.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((float2)float.PositiveInfinity, (float2)float.PositiveInfinity), (float2)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((float2)float.MinValue, (float2)float.NegativeInfinity), (float2)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((float2)float.MinValue, (float2)float.PositiveInfinity), (float2)maxmath.nextgreater(float.MinValue)); + Assert.AreEqual(maxmath.nexttoward((float2)float.MaxValue, (float2)float.NegativeInfinity), (float2)maxmath.nextsmaller(float.MaxValue)); + Assert.AreEqual(maxmath.nexttoward((float2)float.MaxValue, (float2)float.PositiveInfinity), (float2)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((float2)0f, (float2)float.PositiveInfinity), (float2)float.Epsilon); + Assert.AreEqual(maxmath.nexttoward((float2)0f, (float2)float.NegativeInfinity), (float2)(-float.Epsilon)); + Assert.AreEqual(maxmath.nexttoward((float2)math.asfloat(0x8000_0000), (float2)float.PositiveInfinity), (float2)float.Epsilon); + Assert.AreEqual(maxmath.nexttoward((float2)math.asfloat(0x8000_0000), (float2)float.NegativeInfinity), (float2)(-float.Epsilon)); + + for (int i = 0; i < 25; i++) + { + float2 from = rng.NextFloat2(float.MinValue / 2, float.MaxValue / 2); + float2 to = rng.NextFloat2(float.MinValue / 2, float.MaxValue / 2); + float2 next = maxmath.nexttoward(from, to); + + for (int j = 0; j < 2; j++) + { + Assert.AreEqual(from[j], maxmath.nexttoward(from, from)[j]); + + if (from[j] < to[j]) + { + Assert.AreEqual(maxmath.nextgreater(from)[j], next[j]); + } + else if (from[j] > to[j]) + { + Assert.AreEqual(maxmath.nextsmaller(from)[j], next[j]); + } + else + { + Assert.AreEqual(from[j], next[j]); + } + } + } + } + + [Test] + public static void _float3() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nexttoward(rng.NextFloat3(), (float3)float.NaN).x); + Assert.IsNaN(maxmath.nexttoward((float3)float.NaN, rng.NextFloat3()).x); + Assert.IsNaN(maxmath.nexttoward((float3)0f, (float3)float.NaN).x); + Assert.IsNaN(maxmath.nexttoward((float3)float.NaN, (float3)0f).x); + Assert.IsNaN(maxmath.nexttoward((float3)float.NaN, (float3)float.NaN).x); + + Assert.AreEqual(maxmath.nexttoward((float3)float.NegativeInfinity, (float3)float.NegativeInfinity), (float3)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((float3)float.NegativeInfinity, (float3)float.PositiveInfinity), (float3)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((float3)float.PositiveInfinity, (float3)float.NegativeInfinity), (float3)float.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((float3)float.PositiveInfinity, (float3)float.PositiveInfinity), (float3)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((float3)float.MinValue, (float3)float.NegativeInfinity), (float3)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((float3)float.MinValue, (float3)float.PositiveInfinity), (float3)maxmath.nextgreater(float.MinValue)); + Assert.AreEqual(maxmath.nexttoward((float3)float.MaxValue, (float3)float.NegativeInfinity), (float3)maxmath.nextsmaller(float.MaxValue)); + Assert.AreEqual(maxmath.nexttoward((float3)float.MaxValue, (float3)float.PositiveInfinity), (float3)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((float3)0f, (float3)float.PositiveInfinity), (float3)float.Epsilon); + Assert.AreEqual(maxmath.nexttoward((float3)0f, (float3)float.NegativeInfinity), (float3)(-float.Epsilon)); + Assert.AreEqual(maxmath.nexttoward((float3)math.asfloat(0x8000_0000), (float3)float.PositiveInfinity), (float3)float.Epsilon); + Assert.AreEqual(maxmath.nexttoward((float3)math.asfloat(0x8000_0000), (float3)float.NegativeInfinity), (float3)(-float.Epsilon)); + + for (int i = 0; i < 25; i++) + { + float3 from = rng.NextFloat3(float.MinValue / 2, float.MaxValue / 2); + float3 to = rng.NextFloat3(float.MinValue / 2, float.MaxValue / 2); + float3 next = maxmath.nexttoward(from, to); + + for (int j = 0; j < 3; j++) + { + Assert.AreEqual(from[j], maxmath.nexttoward(from, from)[j]); + + if (from[j] < to[j]) + { + Assert.AreEqual(maxmath.nextgreater(from)[j], next[j]); + } + else if (from[j] > to[j]) + { + Assert.AreEqual(maxmath.nextsmaller(from)[j], next[j]); + } + else + { + Assert.AreEqual(from[j], next[j]); + } + } + } + } + + [Test] + public static void _float4() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nexttoward(rng.NextFloat4(), (float4)float.NaN).x); + Assert.IsNaN(maxmath.nexttoward((float4)float.NaN, rng.NextFloat4()).x); + Assert.IsNaN(maxmath.nexttoward((float4)0f, (float4)float.NaN).x); + Assert.IsNaN(maxmath.nexttoward((float4)float.NaN, (float4)0f).x); + Assert.IsNaN(maxmath.nexttoward((float4)float.NaN, (float4)float.NaN).x); + + Assert.AreEqual(maxmath.nexttoward((float4)float.NegativeInfinity, (float4)float.NegativeInfinity), (float4)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((float4)float.NegativeInfinity, (float4)float.PositiveInfinity), (float4)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((float4)float.PositiveInfinity, (float4)float.NegativeInfinity), (float4)float.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((float4)float.PositiveInfinity, (float4)float.PositiveInfinity), (float4)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((float4)float.MinValue, (float4)float.NegativeInfinity), (float4)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((float4)float.MinValue, (float4)float.PositiveInfinity), (float4)maxmath.nextgreater(float.MinValue)); + Assert.AreEqual(maxmath.nexttoward((float4)float.MaxValue, (float4)float.NegativeInfinity), (float4)maxmath.nextsmaller(float.MaxValue)); + Assert.AreEqual(maxmath.nexttoward((float4)float.MaxValue, (float4)float.PositiveInfinity), (float4)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((float4)0f, (float4)float.PositiveInfinity), (float4)float.Epsilon); + Assert.AreEqual(maxmath.nexttoward((float4)0f, (float4)float.NegativeInfinity), (float4)(-float.Epsilon)); + Assert.AreEqual(maxmath.nexttoward((float4)math.asfloat(0x8000_0000), (float4)float.PositiveInfinity), (float4)float.Epsilon); + Assert.AreEqual(maxmath.nexttoward((float4)math.asfloat(0x8000_0000), (float4)float.NegativeInfinity), (float4)(-float.Epsilon)); + + for (int i = 0; i < 25; i++) + { + float4 from = rng.NextFloat4(float.MinValue / 2, float.MaxValue / 2); + float4 to = rng.NextFloat4(float.MinValue / 2, float.MaxValue / 2); + float4 next = maxmath.nexttoward(from, to); + + for (int j = 0; j < 4; j++) + { + Assert.AreEqual(from[j], maxmath.nexttoward(from, from)[j]); + + if (from[j] < to[j]) + { + Assert.AreEqual(maxmath.nextgreater(from)[j], next[j]); + } + else if (from[j] > to[j]) + { + Assert.AreEqual(maxmath.nextsmaller(from)[j], next[j]); + } + else + { + Assert.AreEqual(from[j], next[j]); + } + } + } + } + + [Test] + public static void _float8() + { + Random32 rng = Random32.New; + + Assert.IsNaN(maxmath.nexttoward(rng.NextFloat8(), (float8)float.NaN).x0); + Assert.IsNaN(maxmath.nexttoward((float8)float.NaN, rng.NextFloat8()).x0); + Assert.IsNaN(maxmath.nexttoward((float8)0f, (float8)float.NaN).x0); + Assert.IsNaN(maxmath.nexttoward((float8)float.NaN, (float8)0f).x0); + Assert.IsNaN(maxmath.nexttoward((float8)float.NaN, (float8)float.NaN).x0); + + Assert.AreEqual(maxmath.nexttoward((float8)float.NegativeInfinity, (float8)float.NegativeInfinity), (float8)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((float8)float.NegativeInfinity, (float8)float.PositiveInfinity), (float8)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((float8)float.PositiveInfinity, (float8)float.NegativeInfinity), (float8)float.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((float8)float.PositiveInfinity, (float8)float.PositiveInfinity), (float8)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((float8)float.MinValue, (float8)float.NegativeInfinity), (float8)float.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((float8)float.MinValue, (float8)float.PositiveInfinity), (float8)maxmath.nextgreater(float.MinValue)); + Assert.AreEqual(maxmath.nexttoward((float8)float.MaxValue, (float8)float.NegativeInfinity), (float8)maxmath.nextsmaller(float.MaxValue)); + Assert.AreEqual(maxmath.nexttoward((float8)float.MaxValue, (float8)float.PositiveInfinity), (float8)float.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((float8)0f, (float8)float.PositiveInfinity), (float8)float.Epsilon); + Assert.AreEqual(maxmath.nexttoward((float8)0f, (float8)float.NegativeInfinity), (float8)(-float.Epsilon)); + Assert.AreEqual(maxmath.nexttoward((float8)math.asfloat(0x8000_0000), (float8)float.PositiveInfinity), (float8)float.Epsilon); + Assert.AreEqual(maxmath.nexttoward((float8)math.asfloat(0x8000_0000), (float8)float.NegativeInfinity), (float8)(-float.Epsilon)); + + for (int i = 0; i < 25; i++) + { + float8 from = rng.NextFloat8(float.MinValue / 2, float.MaxValue / 2); + float8 to = rng.NextFloat8(float.MinValue / 2, float.MaxValue / 2); + float8 next = maxmath.nexttoward(from, to); + + for (int j = 0; j < 8; j++) + { + Assert.AreEqual(from[j], maxmath.nexttoward(from, from)[j]); + + if (from[j] < to[j]) + { + Assert.AreEqual(maxmath.nextgreater(from)[j], next[j]); + } + else if (from[j] > to[j]) + { + Assert.AreEqual(maxmath.nextsmaller(from)[j], next[j]); + } + else + { + Assert.AreEqual(from[j], next[j]); + } + } + } + } + + + [Test] + public static void _double() + { + Random64 rng = Random64.New; + + Assert.IsNaN(maxmath.nexttoward(rng.NextDouble(), double.NaN)); + Assert.IsNaN(maxmath.nexttoward(double.NaN, rng.NextDouble())); + Assert.IsNaN(maxmath.nexttoward(0f, double.NaN)); + Assert.IsNaN(maxmath.nexttoward(double.NaN, 0f)); + Assert.IsNaN(maxmath.nexttoward(double.NaN, double.NaN)); + + Assert.AreEqual(maxmath.nexttoward(double.NegativeInfinity, double.NegativeInfinity), double.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward(double.NegativeInfinity, double.PositiveInfinity), double.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward(double.PositiveInfinity, double.NegativeInfinity), double.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward(double.PositiveInfinity, double.PositiveInfinity), double.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward(double.MinValue, double.NegativeInfinity), double.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward(double.MinValue, double.PositiveInfinity), maxmath.nextgreater(double.MinValue)); + Assert.AreEqual(maxmath.nexttoward(double.MaxValue, double.NegativeInfinity), maxmath.nextsmaller(double.MaxValue)); + Assert.AreEqual(maxmath.nexttoward(double.MaxValue, double.PositiveInfinity), double.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward(0f, double.PositiveInfinity), double.Epsilon); + Assert.AreEqual(maxmath.nexttoward(0f, double.NegativeInfinity), -double.Epsilon); + Assert.AreEqual(maxmath.nexttoward(math.asdouble(0x8000_0000_0000_0000), double.PositiveInfinity), double.Epsilon); + Assert.AreEqual(maxmath.nexttoward(math.asdouble(0x8000_0000_0000_0000), double.NegativeInfinity), -double.Epsilon); + + for (int i = 0; i < 25; i++) + { + double from = rng.NextDouble(double.MinValue / 2, double.MaxValue / 2); + double to = rng.NextDouble(double.MinValue / 2, double.MaxValue / 2); + double next = maxmath.nexttoward(from, to); + + Assert.AreEqual(from, maxmath.nexttoward(from, from)); + + if (from < to) + { + Assert.AreEqual(maxmath.nextgreater(from), next); + } + else if (from > to) + { + Assert.AreEqual(maxmath.nextsmaller(from), next); + } + else + { + Assert.AreEqual(from, next); + } + } + } + + [Test] + public static void _double2() + { + Random64 rng = Random64.New; + + Assert.IsNaN(maxmath.nexttoward(rng.NextDouble2(), (double2)double.NaN).x); + Assert.IsNaN(maxmath.nexttoward((double2)double.NaN, rng.NextDouble2()).x); + Assert.IsNaN(maxmath.nexttoward((double2)0f, (double2)double.NaN).x); + Assert.IsNaN(maxmath.nexttoward((double2)double.NaN, (double2)0f).x); + Assert.IsNaN(maxmath.nexttoward((double2)double.NaN, (double2)double.NaN).x); + + Assert.AreEqual(maxmath.nexttoward((double2)double.NegativeInfinity, (double2)double.NegativeInfinity), (double2)double.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((double2)double.NegativeInfinity, (double2)double.PositiveInfinity), (double2)double.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((double2)double.PositiveInfinity, (double2)double.NegativeInfinity), (double2)double.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((double2)double.PositiveInfinity, (double2)double.PositiveInfinity), (double2)double.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((double2)double.MinValue, (double2)double.NegativeInfinity), (double2)double.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((double2)double.MinValue, (double2)double.PositiveInfinity), (double2)maxmath.nextgreater(double.MinValue)); + Assert.AreEqual(maxmath.nexttoward((double2)double.MaxValue, (double2)double.NegativeInfinity), (double2)maxmath.nextsmaller(double.MaxValue)); + Assert.AreEqual(maxmath.nexttoward((double2)double.MaxValue, (double2)double.PositiveInfinity), (double2)double.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((double2)0f, (double2)double.PositiveInfinity), (double2)double.Epsilon); + Assert.AreEqual(maxmath.nexttoward((double2)0f, (double2)double.NegativeInfinity), (double2)(-double.Epsilon)); + Assert.AreEqual(maxmath.nexttoward((double2)math.asdouble(0x8000_0000_0000_0000), (double2)double.PositiveInfinity), (double2)double.Epsilon); + Assert.AreEqual(maxmath.nexttoward((double2)math.asdouble(0x8000_0000_0000_0000), (double2)double.NegativeInfinity), (double2)(-double.Epsilon)); + + for (int i = 0; i < 25; i++) + { + double2 from = rng.NextDouble2(double.MinValue / 2, double.MaxValue / 2); + double2 to = rng.NextDouble2(double.MinValue / 2, double.MaxValue / 2); + double2 next = maxmath.nexttoward(from, to); + + for (int j = 0; j < 2; j++) + { + Assert.AreEqual(from[j], maxmath.nexttoward(from, from)[j]); + + if (from[j] < to[j]) + { + Assert.AreEqual(maxmath.nextgreater(from)[j], next[j]); + } + else if (from[j] > to[j]) + { + Assert.AreEqual(maxmath.nextsmaller(from)[j], next[j]); + } + else + { + Assert.AreEqual(from[j], next[j]); + } + } + } + } + + [Test] + public static void _double3() + { + Random64 rng = Random64.New; + + Assert.IsNaN(maxmath.nexttoward(rng.NextDouble3(), (double3)double.NaN).x); + Assert.IsNaN(maxmath.nexttoward((double3)double.NaN, rng.NextDouble3()).x); + Assert.IsNaN(maxmath.nexttoward((double3)0f, (double3)double.NaN).x); + Assert.IsNaN(maxmath.nexttoward((double3)double.NaN, (double3)0f).x); + Assert.IsNaN(maxmath.nexttoward((double3)double.NaN, (double3)double.NaN).x); + + Assert.AreEqual(maxmath.nexttoward((double3)double.NegativeInfinity, (double3)double.NegativeInfinity), (double3)double.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((double3)double.NegativeInfinity, (double3)double.PositiveInfinity), (double3)double.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((double3)double.PositiveInfinity, (double3)double.NegativeInfinity), (double3)double.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((double3)double.PositiveInfinity, (double3)double.PositiveInfinity), (double3)double.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((double3)double.MinValue, (double3)double.NegativeInfinity), (double3)double.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((double3)double.MinValue, (double3)double.PositiveInfinity), (double3)maxmath.nextgreater(double.MinValue)); + Assert.AreEqual(maxmath.nexttoward((double3)double.MaxValue, (double3)double.NegativeInfinity), (double3)maxmath.nextsmaller(double.MaxValue)); + Assert.AreEqual(maxmath.nexttoward((double3)double.MaxValue, (double3)double.PositiveInfinity), (double3)double.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((double3)0f, (double3)double.PositiveInfinity), (double3)double.Epsilon); + Assert.AreEqual(maxmath.nexttoward((double3)0f, (double3)double.NegativeInfinity), (double3)(-double.Epsilon)); + Assert.AreEqual(maxmath.nexttoward((double3)math.asdouble(0x8000_0000_0000_0000), (double3)double.PositiveInfinity), (double3)double.Epsilon); + Assert.AreEqual(maxmath.nexttoward((double3)math.asdouble(0x8000_0000_0000_0000), (double3)double.NegativeInfinity), (double3)(-double.Epsilon)); + + for (int i = 0; i < 25; i++) + { + double3 from = rng.NextDouble3(double.MinValue / 2, double.MaxValue / 2); + double3 to = rng.NextDouble3(double.MinValue / 2, double.MaxValue / 2); + double3 next = maxmath.nexttoward(from, to); + + for (int j = 0; j < 3; j++) + { + Assert.AreEqual(from[j], maxmath.nexttoward(from, from)[j]); + + if (from[j] < to[j]) + { + Assert.AreEqual(maxmath.nextgreater(from)[j], next[j]); + } + else if (from[j] > to[j]) + { + Assert.AreEqual(maxmath.nextsmaller(from)[j], next[j]); + } + else + { + Assert.AreEqual(from[j], next[j]); + } + } + } + } + + [Test] + public static void _double4() + { + Random64 rng = Random64.New; + + Assert.IsNaN(maxmath.nexttoward(rng.NextDouble4(), (double4)double.NaN).x); + Assert.IsNaN(maxmath.nexttoward((double4)double.NaN, rng.NextDouble4()).x); + Assert.IsNaN(maxmath.nexttoward((double4)0f, (double4)double.NaN).x); + Assert.IsNaN(maxmath.nexttoward((double4)double.NaN, (double4)0f).x); + Assert.IsNaN(maxmath.nexttoward((double4)double.NaN, (double4)double.NaN).x); + + Assert.AreEqual(maxmath.nexttoward((double4)double.NegativeInfinity, (double4)double.NegativeInfinity), (double4)double.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((double4)double.NegativeInfinity, (double4)double.PositiveInfinity), (double4)double.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((double4)double.PositiveInfinity, (double4)double.NegativeInfinity), (double4)double.PositiveInfinity); + Assert.AreEqual(maxmath.nexttoward((double4)double.PositiveInfinity, (double4)double.PositiveInfinity), (double4)double.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((double4)double.MinValue, (double4)double.NegativeInfinity), (double4)double.NegativeInfinity); + Assert.AreEqual(maxmath.nexttoward((double4)double.MinValue, (double4)double.PositiveInfinity), (double4)maxmath.nextgreater(double.MinValue)); + Assert.AreEqual(maxmath.nexttoward((double4)double.MaxValue, (double4)double.NegativeInfinity), (double4)maxmath.nextsmaller(double.MaxValue)); + Assert.AreEqual(maxmath.nexttoward((double4)double.MaxValue, (double4)double.PositiveInfinity), (double4)double.PositiveInfinity); + + Assert.AreEqual(maxmath.nexttoward((double4)0f, (double4)double.PositiveInfinity), (double4)double.Epsilon); + Assert.AreEqual(maxmath.nexttoward((double4)0f, (double4)double.NegativeInfinity), (double4)(-double.Epsilon)); + Assert.AreEqual(maxmath.nexttoward((double4)math.asdouble(0x8000_0000_0000_0000), (double4)double.PositiveInfinity), (double4)double.Epsilon); + Assert.AreEqual(maxmath.nexttoward((double4)math.asdouble(0x8000_0000_0000_0000), (double4)double.NegativeInfinity), (double4)(-double.Epsilon)); + + for (int i = 0; i < 25; i++) + { + double4 from = rng.NextDouble4(double.MinValue / 2, double.MaxValue / 2); + double4 to = rng.NextDouble4(double.MinValue / 2, double.MaxValue / 2); + double4 next = maxmath.nexttoward(from, to); + + for (int j = 0; j < 4; j++) + { + Assert.AreEqual(from[j], maxmath.nexttoward(from, from)[j]); + + if (from[j] < to[j]) + { + Assert.AreEqual(maxmath.nextgreater(from)[j], next[j]); + } + else if (from[j] > to[j]) + { + Assert.AreEqual(maxmath.nextsmaller(from)[j], next[j]); + } + else + { + Assert.AreEqual(from[j], next[j]); + } + } + } + } + } +} diff --git a/Tests/Editor/Functions/Arithmetic/nexttoward.cs.meta b/Tests/Editor/Functions/Arithmetic/nexttoward.cs.meta new file mode 100644 index 0000000..bfea0fc --- /dev/null +++ b/Tests/Editor/Functions/Arithmetic/nexttoward.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9ac01b8ea11833c478c126236f4b5c83 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Editor/Functions/Arithmetic/sad.cs b/Tests/Editor/Functions/Arithmetic/sad.cs index 31981a9..ae4867d 100644 --- a/Tests/Editor/Functions/Arithmetic/sad.cs +++ b/Tests/Editor/Functions/Arithmetic/sad.cs @@ -1,6 +1,5 @@ using NUnit.Framework; using Unity.Mathematics; -using Unity.Burst.Intrinsics; namespace MaxMath.Tests { diff --git a/Tests/Editor/Functions/Bitwise/BMI/bits_depositparallel.cs b/Tests/Editor/Functions/Bitwise/BMI/bits_depositparallel.cs index 7611abc..a6e8268 100644 --- a/Tests/Editor/Functions/Bitwise/BMI/bits_depositparallel.cs +++ b/Tests/Editor/Functions/Bitwise/BMI/bits_depositparallel.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using NUnit.Framework; using Unity.Mathematics; diff --git a/Tests/Editor/Functions/Bitwise/BMI/bits_extract.cs b/Tests/Editor/Functions/Bitwise/BMI/bits_extract.cs index a06aae9..b263569 100644 --- a/Tests/Editor/Functions/Bitwise/BMI/bits_extract.cs +++ b/Tests/Editor/Functions/Bitwise/BMI/bits_extract.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Bitwise/BMI/bits_extractlowest.cs b/Tests/Editor/Functions/Bitwise/BMI/bits_extractlowest.cs index 9d134ed..27a71a0 100644 --- a/Tests/Editor/Functions/Bitwise/BMI/bits_extractlowest.cs +++ b/Tests/Editor/Functions/Bitwise/BMI/bits_extractlowest.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Bitwise/BMI/bits_extractparallel.cs b/Tests/Editor/Functions/Bitwise/BMI/bits_extractparallel.cs index 4393811..6da85ff 100644 --- a/Tests/Editor/Functions/Bitwise/BMI/bits_extractparallel.cs +++ b/Tests/Editor/Functions/Bitwise/BMI/bits_extractparallel.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using NUnit.Framework; using Unity.Mathematics; diff --git a/Tests/Editor/Functions/Bitwise/BMI/bits_mastolowest.cs b/Tests/Editor/Functions/Bitwise/BMI/bits_mastolowest.cs index 685373a..a68a6c8 100644 --- a/Tests/Editor/Functions/Bitwise/BMI/bits_mastolowest.cs +++ b/Tests/Editor/Functions/Bitwise/BMI/bits_mastolowest.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Bitwise/BMI/bits_resetlowest.cs b/Tests/Editor/Functions/Bitwise/BMI/bits_resetlowest.cs index b18d879..a3c7c10 100644 --- a/Tests/Editor/Functions/Bitwise/BMI/bits_resetlowest.cs +++ b/Tests/Editor/Functions/Bitwise/BMI/bits_resetlowest.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Bitwise/BMI/bits_zerohigh.cs b/Tests/Editor/Functions/Bitwise/BMI/bits_zerohigh.cs index f8aba90..d7078e0 100644 --- a/Tests/Editor/Functions/Bitwise/BMI/bits_zerohigh.cs +++ b/Tests/Editor/Functions/Bitwise/BMI/bits_zerohigh.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Bitwise/BitTest/testbit.cs b/Tests/Editor/Functions/Bitwise/BitTest/testbit.cs index 233ff28..b74ca96 100644 --- a/Tests/Editor/Functions/Bitwise/BitTest/testbit.cs +++ b/Tests/Editor/Functions/Bitwise/BitTest/testbit.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Bitwise/BitTest/testbitflip.cs b/Tests/Editor/Functions/Bitwise/BitTest/testbitflip.cs index c5b46ae..b45acea 100644 --- a/Tests/Editor/Functions/Bitwise/BitTest/testbitflip.cs +++ b/Tests/Editor/Functions/Bitwise/BitTest/testbitflip.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Bitwise/BitTest/testbitreset.cs b/Tests/Editor/Functions/Bitwise/BitTest/testbitreset.cs index 5f19594..2f69b9f 100644 --- a/Tests/Editor/Functions/Bitwise/BitTest/testbitreset.cs +++ b/Tests/Editor/Functions/Bitwise/BitTest/testbitreset.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Bitwise/BitTest/testbitset.cs b/Tests/Editor/Functions/Bitwise/BitTest/testbitset.cs index 656ac86..667f2e4 100644 --- a/Tests/Editor/Functions/Bitwise/BitTest/testbitset.cs +++ b/Tests/Editor/Functions/Bitwise/BitTest/testbitset.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Bitwise/shift_varying.cs b/Tests/Editor/Functions/Bitwise/shift_varying.cs index 8b24e7a..eef496e 100644 --- a/Tests/Editor/Functions/Bitwise/shift_varying.cs +++ b/Tests/Editor/Functions/Bitwise/shift_varying.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Comparison/cmax.cs b/Tests/Editor/Functions/Comparison/cmax.cs index fd93634..9256fff 100644 --- a/Tests/Editor/Functions/Comparison/cmax.cs +++ b/Tests/Editor/Functions/Comparison/cmax.cs @@ -1,6 +1,5 @@ using NUnit.Framework; using Unity.Mathematics; -using Unity.Burst.Intrinsics; namespace MaxMath.Tests { diff --git a/Tests/Editor/Functions/Comparison/cmaxmag.cs b/Tests/Editor/Functions/Comparison/cmaxmag.cs index 9fec64f..8ad1362 100644 --- a/Tests/Editor/Functions/Comparison/cmaxmag.cs +++ b/Tests/Editor/Functions/Comparison/cmaxmag.cs @@ -1,6 +1,5 @@ using NUnit.Framework; using Unity.Mathematics; -using Unity.Burst.Intrinsics; namespace MaxMath.Tests { diff --git a/Tests/Editor/Functions/Comparison/cmin.cs b/Tests/Editor/Functions/Comparison/cmin.cs index cae1a48..d1638c1 100644 --- a/Tests/Editor/Functions/Comparison/cmin.cs +++ b/Tests/Editor/Functions/Comparison/cmin.cs @@ -1,6 +1,5 @@ using NUnit.Framework; using Unity.Mathematics; -using Unity.Burst.Intrinsics; namespace MaxMath.Tests { diff --git a/Tests/Editor/Functions/Comparison/cminmag.cs b/Tests/Editor/Functions/Comparison/cminmag.cs index e4fd421..e04e222 100644 --- a/Tests/Editor/Functions/Comparison/cminmag.cs +++ b/Tests/Editor/Functions/Comparison/cminmag.cs @@ -1,6 +1,5 @@ using NUnit.Framework; using Unity.Mathematics; -using Unity.Burst.Intrinsics; namespace MaxMath.Tests { diff --git a/Tests/Editor/Functions/Comparison/cminmax.cs b/Tests/Editor/Functions/Comparison/cminmax.cs index 291c44e..f4471b3 100644 --- a/Tests/Editor/Functions/Comparison/cminmax.cs +++ b/Tests/Editor/Functions/Comparison/cminmax.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Comparison/cminmaxmag.cs b/Tests/Editor/Functions/Comparison/cminmaxmag.cs index 79e8fe4..6133eb6 100644 --- a/Tests/Editor/Functions/Comparison/cminmaxmag.cs +++ b/Tests/Editor/Functions/Comparison/cminmaxmag.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Comparison/compareto.cs b/Tests/Editor/Functions/Comparison/compareto.cs index ca86a8a..4f86c90 100644 --- a/Tests/Editor/Functions/Comparison/compareto.cs +++ b/Tests/Editor/Functions/Comparison/compareto.cs @@ -127,6 +127,169 @@ public static void UInt128() } } + [Test] + public static void Quarter() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 20; i++) + { + quarter l = (quarter)rng.NextFloat(quarter.MinValue, quarter.MaxValue); + quarter r = (quarter)rng.NextFloat(quarter.MinValue, quarter.MaxValue); + + Assert.AreEqual(((float)l).CompareTo(r), maxmath.compareto(l, r)); + } + } + + [Test] + public static void Quarter2() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 20; i++) + { + quarter2 l = (quarter2)rng.NextFloat2(quarter.MinValue, quarter.MaxValue); + quarter2 r = (quarter2)rng.NextFloat2(quarter.MinValue, quarter.MaxValue); + + for (int j = 0; j < 2; j++) + { + Assert.AreEqual(((float)l[j]).CompareTo(r[j]), maxmath.compareto(l, r)[j]); + } + } + } + + [Test] + public static void Quarter3() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 20; i++) + { + quarter3 l = (quarter3)rng.NextFloat3(quarter.MinValue, quarter.MaxValue); + quarter3 r = (quarter3)rng.NextFloat3(quarter.MinValue, quarter.MaxValue); + + for (int j = 0; j < 3; j++) + { + Assert.AreEqual(((float)l[j]).CompareTo(r[j]), maxmath.compareto(l, r)[j]); + } + } + } + + [Test] + public static void Quarter4() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 20; i++) + { + quarter4 l = (quarter4)rng.NextFloat4(quarter.MinValue, quarter.MaxValue); + quarter4 r = (quarter4)rng.NextFloat4(quarter.MinValue, quarter.MaxValue); + + for (int j = 0; j < 4; j++) + { + Assert.AreEqual(((float)l[j]).CompareTo(r[j]), maxmath.compareto(l, r)[j]); + } + } + } + + [Test] + public static void Quarter8() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 20; i++) + { + quarter8 l = (quarter8)rng.NextFloat8(quarter.MinValue, quarter.MaxValue); + quarter8 r = (quarter8)rng.NextFloat8(quarter.MinValue, quarter.MaxValue); + + for (int j = 0; j < 8; j++) + { + Assert.AreEqual(((float)l[j]).CompareTo(r[j]), maxmath.compareto(l, r)[j]); + } + } + } + [Test] + public static void Half() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 20; i++) + { + half l = (half)rng.NextFloat(half.MinValue, half.MaxValue); + half r = (half)rng.NextFloat(half.MinValue, half.MaxValue); + + Assert.AreEqual(((float)l).CompareTo(r), maxmath.compareto(l, r)); + } + } + + [Test] + public static void Half2() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 20; i++) + { + half2 l = (half2)rng.NextFloat2(half.MinValue, half.MaxValue); + half2 r = (half2)rng.NextFloat2(half.MinValue, half.MaxValue); + + for (int j = 0; j < 2; j++) + { + Assert.AreEqual(((float)l[j]).CompareTo(r[j]), maxmath.compareto(l, r)[j]); + } + } + } + + [Test] + public static void Half3() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 20; i++) + { + half3 l = (half3)rng.NextFloat3(half.MinValue, half.MaxValue); + half3 r = (half3)rng.NextFloat3(half.MinValue, half.MaxValue); + + for (int j = 0; j < 3; j++) + { + Assert.AreEqual(((float)l[j]).CompareTo(r[j]), maxmath.compareto(l, r)[j]); + } + } + } + + [Test] + public static void Half4() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 20; i++) + { + half4 l = (half4)rng.NextFloat4(half.MinValue, half.MaxValue); + half4 r = (half4)rng.NextFloat4(half.MinValue, half.MaxValue); + + for (int j = 0; j < 4; j++) + { + Assert.AreEqual(((float)l[j]).CompareTo(r[j]), maxmath.compareto(l, r)[j]); + } + } + } + + [Test] + public static void Half8() + { + Random32 rng = Random32.New; + + for (int i = 0; i < 20; i++) + { + half8 l = (half8)rng.NextFloat8(half.MinValue, half.MaxValue); + half8 r = (half8)rng.NextFloat8(half.MinValue, half.MaxValue); + + for (int j = 0; j < 8; j++) + { + Assert.AreEqual(((float)l[j]).CompareTo(r[j]), maxmath.compareto(l, r)[j]); + } + } + } + [Test] public static void Float() { diff --git a/Tests/Editor/Functions/Comparison/count.cs b/Tests/Editor/Functions/Comparison/count.cs index 0a2b1da..2eb9a5a 100644 --- a/Tests/Editor/Functions/Comparison/count.cs +++ b/Tests/Editor/Functions/Comparison/count.cs @@ -1,6 +1,5 @@ using NUnit.Framework; using Unity.Mathematics; -using Unity.Burst.Intrinsics; namespace MaxMath.Tests { diff --git a/Tests/Editor/Functions/Comparison/first.cs b/Tests/Editor/Functions/Comparison/first.cs index ed7b4ab..ca3284f 100644 --- a/Tests/Editor/Functions/Comparison/first.cs +++ b/Tests/Editor/Functions/Comparison/first.cs @@ -1,6 +1,5 @@ using NUnit.Framework; using Unity.Mathematics; -using Unity.Burst.Intrinsics; namespace MaxMath.Tests { diff --git a/Tests/Editor/Functions/Comparison/ispow2.cs b/Tests/Editor/Functions/Comparison/ispow2.cs index 67017c2..ebf4ddb 100644 --- a/Tests/Editor/Functions/Comparison/ispow2.cs +++ b/Tests/Editor/Functions/Comparison/ispow2.cs @@ -1,6 +1,5 @@ using NUnit.Framework; using Unity.Mathematics; -using MaxMath; namespace MaxMath.Tests { diff --git a/Tests/Editor/Functions/Comparison/maxmag.cs b/Tests/Editor/Functions/Comparison/maxmag.cs index 03369b3..b792946 100644 --- a/Tests/Editor/Functions/Comparison/maxmag.cs +++ b/Tests/Editor/Functions/Comparison/maxmag.cs @@ -1,6 +1,5 @@ using NUnit.Framework; using Unity.Mathematics; -using Unity.Burst.Intrinsics; namespace MaxMath.Tests { diff --git a/Tests/Editor/Functions/Comparison/minmag.cs b/Tests/Editor/Functions/Comparison/minmag.cs index b554e44..7da3cb4 100644 --- a/Tests/Editor/Functions/Comparison/minmag.cs +++ b/Tests/Editor/Functions/Comparison/minmag.cs @@ -1,6 +1,5 @@ using NUnit.Framework; using Unity.Mathematics; -using Unity.Burst.Intrinsics; namespace MaxMath.Tests { diff --git a/Tests/Editor/Functions/Comparison/minmax.cs b/Tests/Editor/Functions/Comparison/minmax.cs index 3845d46..f4d5bf1 100644 --- a/Tests/Editor/Functions/Comparison/minmax.cs +++ b/Tests/Editor/Functions/Comparison/minmax.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Comparison/minmaxmag.cs b/Tests/Editor/Functions/Comparison/minmaxmag.cs index 3292a29..f91e1f5 100644 --- a/Tests/Editor/Functions/Comparison/minmaxmag.cs +++ b/Tests/Editor/Functions/Comparison/minmaxmag.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/(r)cbrt.cs b/Tests/Editor/Functions/Promises/(r)cbrt.cs index c4eff91..4653b00 100644 --- a/Tests/Editor/Functions/Promises/(r)cbrt.cs +++ b/Tests/Editor/Functions/Promises/(r)cbrt.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/avg.cs b/Tests/Editor/Functions/Promises/avg.cs index 8721cd3..2205d6b 100644 --- a/Tests/Editor/Functions/Promises/avg.cs +++ b/Tests/Editor/Functions/Promises/avg.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/cavg.cs b/Tests/Editor/Functions/Promises/cavg.cs index cef9fd4..bfd5f0e 100644 --- a/Tests/Editor/Functions/Promises/cavg.cs +++ b/Tests/Editor/Functions/Promises/cavg.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/cmaxmag.cs b/Tests/Editor/Functions/Promises/cmaxmag.cs index 70f092f..197d4b2 100644 --- a/Tests/Editor/Functions/Promises/cmaxmag.cs +++ b/Tests/Editor/Functions/Promises/cmaxmag.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/cminmag.cs b/Tests/Editor/Functions/Promises/cminmag.cs index 5ffab96..db34ebe 100644 --- a/Tests/Editor/Functions/Promises/cminmag.cs +++ b/Tests/Editor/Functions/Promises/cminmag.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/cminmaxmag.cs b/Tests/Editor/Functions/Promises/cminmaxmag.cs index 016b691..0339389 100644 --- a/Tests/Editor/Functions/Promises/cminmaxmag.cs +++ b/Tests/Editor/Functions/Promises/cminmaxmag.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/comb.cs b/Tests/Editor/Functions/Promises/comb.cs new file mode 100644 index 0000000..e8cd48e --- /dev/null +++ b/Tests/Editor/Functions/Promises/comb.cs @@ -0,0 +1,1026 @@ +using NUnit.Framework; +using Unity.Mathematics; + +using static MaxMath.LUT.FACTORIAL; +using static MaxMath.maxmath; + +namespace MaxMath.Tests +{ + public static class PROMISE_comb + { + [Test] + public static void _byte2() + { + Random8 rng = Random8.New; + byte2 n; + byte2 k; + byte2 normal; + byte2 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextByte2(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextByte2(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 2; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte2(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextByte2(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 2; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte2(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextByte2(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe2); + for (int j = 0; j < 2; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte2(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextByte2(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe3); + for (int j = 0; j < 2; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + [Test] + public static void _byte3() + { + Random8 rng = Random8.New; + byte3 n; + byte3 k; + byte3 normal; + byte3 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextByte3(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextByte3(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 3; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte3(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextByte3(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 3; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte3(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextByte3(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe2); + for (int j = 0; j < 3; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte3(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextByte3(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe3); + for (int j = 0; j < 3; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + [Test] + public static void _byte4() + { + Random8 rng = Random8.New; + byte4 n; + byte4 k; + byte4 normal; + byte4 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextByte4(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextByte4(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 4; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte4(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextByte4(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 4; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte4(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextByte4(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe2); + for (int j = 0; j < 4; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte4(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextByte4(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe3); + for (int j = 0; j < 4; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + [Test] + public static void _byte8() + { + Random8 rng = Random8.New; + byte8 n; + byte8 k; + byte8 normal; + byte8 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextByte8(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextByte8(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 8; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte8(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextByte8(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 8; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte8(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextByte8(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe2); + for (int j = 0; j < 8; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte8(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextByte8(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe3); + for (int j = 0; j < 8; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + [Test] + public static void _byte16() + { + Random8 rng = Random8.New; + byte16 n; + byte16 k; + byte16 normal; + byte16 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextByte16(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextByte16(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 16; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte16(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextByte16(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 16; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte16(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextByte16(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe2); + for (int j = 0; j < 16; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte16(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextByte16(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe3); + for (int j = 0; j < 16; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + [Test] + public static void _byte32() + { + Random8 rng = Random8.New; + byte32 n; + byte32 k; + byte32 normal; + byte32 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextByte32(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextByte32(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 32; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte32(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextByte32(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 32; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte32(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextByte32(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe2); + for (int j = 0; j < 32; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextByte32(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextByte32(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe3); + for (int j = 0; j < 32; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= byte.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + + [Test] + public static void _ushort2() + { + Random16 rng = Random16.New; + ushort2 n; + ushort2 k; + ushort2 normal; + ushort2 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUShort2(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUShort2(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 2; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUShort2(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUShort2(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 2; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUShort2(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextUShort2(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe2); + for (int j = 0; j < 2; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUShort2(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextUShort2(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe3); + for (int j = 0; j < 2; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + [Test] + public static void _ushort3() + { + Random16 rng = Random16.New; + ushort3 n; + ushort3 k; + ushort3 normal; + ushort3 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUShort3(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUShort3(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 3; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUShort3(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUShort3(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 3; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUShort3(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextUShort3(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe2); + for (int j = 0; j < 3; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUShort3(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextUShort3(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe3); + for (int j = 0; j < 3; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + [Test] + public static void _ushort4() + { + Random16 rng = Random16.New; + ushort4 n; + ushort4 k; + ushort4 normal; + ushort4 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUShort4(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUShort4(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 4; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUShort4(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUShort4(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 4; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUShort4(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextUShort4(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe2); + for (int j = 0; j < 4; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUShort4(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextUShort4(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe3); + for (int j = 0; j < 4; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + [Test] + public static void _ushort8() + { + Random16 rng = Random16.New; + ushort8 n; + ushort8 k; + ushort8 normal; + ushort8 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUShort8(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUShort8(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 8; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUShort8(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUShort8(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 8; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUShort8(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextUShort8(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe2); + for (int j = 0; j < 8; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUShort8(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextUShort8(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe3); + for (int j = 0; j < 8; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + [Test] + public static void _ushort16() + { + Random16 rng = Random16.New; + ushort16 n; + ushort16 k; + ushort16 normal; + ushort16 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUShort16(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUShort16(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 16; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUShort16(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUShort16(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 16; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUShort16(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextUShort16(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe2); + for (int j = 0; j < 16; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUShort16(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextUShort16(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe3); + for (int j = 0; j < 16; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ushort.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + + [Test] + public static void _uint() + { + Random32 rng = Random32.New; + uint n; + uint k; + uint normal; + uint promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUInt(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUInt(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + if (maxmath.comb((UInt128)n, (UInt128)k, Promise.Unsafe0) <= uint.MaxValue) + { + Assert.AreEqual(normal, promise); + } + + n = rng.NextUInt(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUInt(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + if (maxmath.comb((UInt128)n, (UInt128)k, Promise.Unsafe0) <= uint.MaxValue) + { + Assert.AreEqual(normal, promise); + } + } + } + + [Test] + public static void _uint2() + { + Random32 rng = Random32.New; + uint2 n; + uint2 k; + uint2 normal; + uint2 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUInt2(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUInt2(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 2; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= uint.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUInt2(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUInt2(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 2; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= uint.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + [Test] + public static void _uint3() + { + Random32 rng = Random32.New; + uint3 n; + uint3 k; + uint3 normal; + uint3 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUInt3(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUInt3(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 3; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= uint.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUInt3(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUInt3(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 3; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= uint.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + [Test] + public static void _uint4() + { + Random32 rng = Random32.New; + uint4 n; + uint4 k; + uint4 normal; + uint4 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUInt4(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUInt4(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 4; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= uint.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUInt4(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUInt4(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 4; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= uint.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + [Test] + public static void _uint8() + { + Random32 rng = Random32.New; + uint8 n; + uint8 k; + uint8 normal; + uint8 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUInt8(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUInt8(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 8; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= uint.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextUInt8(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUInt8(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 8; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= uint.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + + [Test] + public static void _ulong() + { + Random64 rng = Random64.New; + ulong n; + ulong k; + ulong normal; + ulong promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextULong(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextULong(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + if (maxmath.comb((UInt128)n, (UInt128)k, Promise.Unsafe0) <= ulong.MaxValue) + { + Assert.AreEqual(normal, promise); + } + + n = rng.NextULong(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextULong(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + if (maxmath.comb((UInt128)n, (UInt128)k, Promise.Unsafe0) <= ulong.MaxValue) + { + Assert.AreEqual(normal, promise); + } + } + } + + [Test] + public static void _ulong2() + { + Random64 rng = Random64.New; + ulong2 n; + ulong2 k; + ulong2 normal; + ulong2 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextULong2(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextULong2(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 2; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ulong.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextULong2(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextULong2(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 2; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ulong.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + [Test] + public static void _ulong3() + { + Random64 rng = Random64.New; + ulong3 n; + ulong3 k; + ulong3 normal; + ulong3 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextULong3(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextULong3(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 3; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ulong.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextULong3(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextULong3(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 3; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ulong.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + [Test] + public static void _ulong4() + { + Random64 rng = Random64.New; + ulong4 n; + ulong4 k; + ulong4 normal; + ulong4 promise; + + for (int i = 0; i < 24; i++) + { + n = rng.NextULong4(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextULong4(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe0); + for (int j = 0; j < 4; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ulong.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + + n = rng.NextULong4(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextULong4(0, n + 1); + normal = maxmath.comb(n, k); + promise = maxmath.comb(n, k, maxmath.Promise.Unsafe1); + for (int j = 0; j < 4; j++) + { + if (maxmath.comb((UInt128)n[j], (UInt128)k[j], Promise.Unsafe0) <= ulong.MaxValue) + { + Assert.AreEqual(normal[j], promise[j]); + } + } + } + } + + + [Test] + public static void _uint128() + { + Random128 rng = Random128.New; + UInt128 n; + UInt128 k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUInt128(0, MAX_INVERSE_FACTORIAL_U128 + 1); + k = rng.NextUInt128(0, n + 1); + Assert.AreEqual(maxmath.comb(n, k), maxmath.comb(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextUInt128(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUInt128(0, n + 1); + Assert.AreEqual(maxmath.comb(n, k), maxmath.comb(n, k, maxmath.Promise.Unsafe1)); + } + } + } +} diff --git a/Tests/Editor/Functions/Promises/comb.cs.meta b/Tests/Editor/Functions/Promises/comb.cs.meta new file mode 100644 index 0000000..350be33 --- /dev/null +++ b/Tests/Editor/Functions/Promises/comb.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 371b35ee2f74c8e428b1f6533e780de0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Editor/Functions/Promises/copysign.cs b/Tests/Editor/Functions/Promises/copysign.cs index bf3761c..2b5e4a5 100644 --- a/Tests/Editor/Functions/Promises/copysign.cs +++ b/Tests/Editor/Functions/Promises/copysign.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/cprod.cs b/Tests/Editor/Functions/Promises/cprod.cs index 2c67283..a157e37 100644 --- a/Tests/Editor/Functions/Promises/cprod.cs +++ b/Tests/Editor/Functions/Promises/cprod.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/csum.cs b/Tests/Editor/Functions/Promises/csum.cs index 1a1600c..076ad3d 100644 --- a/Tests/Editor/Functions/Promises/csum.cs +++ b/Tests/Editor/Functions/Promises/csum.cs @@ -1,5 +1,4 @@ -using NUnit.Framework; -using Unity.Mathematics; +using NUnit.Framework; namespace MaxMath.Tests { diff --git a/Tests/Editor/Functions/Promises/dot.cs b/Tests/Editor/Functions/Promises/dot.cs index e995f18..cf9915c 100644 --- a/Tests/Editor/Functions/Promises/dot.cs +++ b/Tests/Editor/Functions/Promises/dot.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/exp2 int.cs b/Tests/Editor/Functions/Promises/exp2 int.cs index e2781fe..7b6827c 100644 --- a/Tests/Editor/Functions/Promises/exp2 int.cs +++ b/Tests/Editor/Functions/Promises/exp2 int.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/factorial.cs b/Tests/Editor/Functions/Promises/factorial.cs index 505d0bc..2ad86b0 100644 --- a/Tests/Editor/Functions/Promises/factorial.cs +++ b/Tests/Editor/Functions/Promises/factorial.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/intcbrt.cs b/Tests/Editor/Functions/Promises/intcbrt.cs index ca12321..2a250fa 100644 --- a/Tests/Editor/Functions/Promises/intcbrt.cs +++ b/Tests/Editor/Functions/Promises/intcbrt.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/maxmag.cs b/Tests/Editor/Functions/Promises/maxmag.cs index 54a6cc7..7ed2e47 100644 --- a/Tests/Editor/Functions/Promises/maxmag.cs +++ b/Tests/Editor/Functions/Promises/maxmag.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/minmag.cs b/Tests/Editor/Functions/Promises/minmag.cs index 7060f09..ea246fb 100644 --- a/Tests/Editor/Functions/Promises/minmag.cs +++ b/Tests/Editor/Functions/Promises/minmag.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/minmaxmag.cs b/Tests/Editor/Functions/Promises/minmaxmag.cs index 600fa28..950a393 100644 --- a/Tests/Editor/Functions/Promises/minmaxmag.cs +++ b/Tests/Editor/Functions/Promises/minmaxmag.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/nextgreater.cs b/Tests/Editor/Functions/Promises/nextgreater.cs new file mode 100644 index 0000000..ecce3e2 --- /dev/null +++ b/Tests/Editor/Functions/Promises/nextgreater.cs @@ -0,0 +1,258 @@ +using NUnit.Framework; +using Unity.Mathematics; + +namespace MaxMath.Tests +{ + public static class PROMISE_nextgreater + { + [Test] + public static void _quarter() + { + Assert.AreEqual(maxmath.nextgreater((quarter)(1.747f)), maxmath.nextgreater((quarter)(1.747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((quarter)(1.747f)), maxmath.nextgreater((quarter)(1.747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((quarter)(1.747f)), maxmath.nextgreater((quarter)(1.747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((quarter)(-1.747f)), maxmath.nextgreater((quarter)(-1.747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((quarter)(1.747f)), maxmath.nextgreater((quarter)(1.747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((quarter)(1.747f)), maxmath.nextgreater((quarter)(1.747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((quarter)(-1.747f)), maxmath.nextgreater((quarter)(-1.747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _quarter2() + { + Assert.AreEqual(maxmath.nextgreater((quarter2)(1.747f)), maxmath.nextgreater((quarter2)(1.747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((quarter2)(1.747f)), maxmath.nextgreater((quarter2)(1.747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((quarter2)(1.747f)), maxmath.nextgreater((quarter2)(1.747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((quarter2)(-1.747f)), maxmath.nextgreater((quarter2)(-1.747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((quarter2)(1.747f)), maxmath.nextgreater((quarter2)(1.747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((quarter2)(1.747f)), maxmath.nextgreater((quarter2)(1.747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((quarter2)(-1.747f)), maxmath.nextgreater((quarter2)(-1.747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _quarter3() + { + Assert.AreEqual(maxmath.nextgreater((quarter3)(1.747f)), maxmath.nextgreater((quarter3)(1.747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((quarter3)(1.747f)), maxmath.nextgreater((quarter3)(1.747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((quarter3)(1.747f)), maxmath.nextgreater((quarter3)(1.747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((quarter3)(-1.747f)), maxmath.nextgreater((quarter3)(-1.747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((quarter3)(1.747f)), maxmath.nextgreater((quarter3)(1.747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((quarter3)(1.747f)), maxmath.nextgreater((quarter3)(1.747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((quarter3)(-1.747f)), maxmath.nextgreater((quarter3)(-1.747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _quarter4() + { + Assert.AreEqual(maxmath.nextgreater((quarter4)(1.747f)), maxmath.nextgreater((quarter4)(1.747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((quarter4)(1.747f)), maxmath.nextgreater((quarter4)(1.747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((quarter4)(1.747f)), maxmath.nextgreater((quarter4)(1.747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((quarter4)(-1.747f)), maxmath.nextgreater((quarter4)(-1.747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((quarter4)(1.747f)), maxmath.nextgreater((quarter4)(1.747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((quarter4)(1.747f)), maxmath.nextgreater((quarter4)(1.747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((quarter4)(-1.747f)), maxmath.nextgreater((quarter4)(-1.747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _quarter8() + { + Assert.AreEqual(maxmath.nextgreater((quarter8)(1.747f)), maxmath.nextgreater((quarter8)(1.747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((quarter8)(1.747f)), maxmath.nextgreater((quarter8)(1.747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((quarter8)(1.747f)), maxmath.nextgreater((quarter8)(1.747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((quarter8)(-1.747f)), maxmath.nextgreater((quarter8)(-1.747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((quarter8)(1.747f)), maxmath.nextgreater((quarter8)(1.747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((quarter8)(1.747f)), maxmath.nextgreater((quarter8)(1.747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((quarter8)(-1.747f)), maxmath.nextgreater((quarter8)(-1.747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + + [Test] + public static void _half() + { + Assert.AreEqual(maxmath.nextgreater((half)(1747f)), maxmath.nextgreater((half)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((half)(1747f)), maxmath.nextgreater((half)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((half)(1747f)), maxmath.nextgreater((half)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((half)(-1747f)), maxmath.nextgreater((half)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((half)(1747f)), maxmath.nextgreater((half)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((half)(1747f)), maxmath.nextgreater((half)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((half)(-1747f)), maxmath.nextgreater((half)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _half2() + { + Assert.AreEqual(maxmath.nextgreater((half2)(1747f)), maxmath.nextgreater((half2)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((half2)(1747f)), maxmath.nextgreater((half2)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((half2)(1747f)), maxmath.nextgreater((half2)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((half2)(-1747f)), maxmath.nextgreater((half2)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((half2)(1747f)), maxmath.nextgreater((half2)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((half2)(1747f)), maxmath.nextgreater((half2)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((half2)(-1747f)), maxmath.nextgreater((half2)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _half3() + { + Assert.AreEqual(maxmath.nextgreater((half3)(1747f)), maxmath.nextgreater((half3)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((half3)(1747f)), maxmath.nextgreater((half3)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((half3)(1747f)), maxmath.nextgreater((half3)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((half3)(-1747f)), maxmath.nextgreater((half3)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((half3)(1747f)), maxmath.nextgreater((half3)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((half3)(1747f)), maxmath.nextgreater((half3)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((half3)(-1747f)), maxmath.nextgreater((half3)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _half4() + { + Assert.AreEqual(maxmath.nextgreater((half4)(1747f)), maxmath.nextgreater((half4)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((half4)(1747f)), maxmath.nextgreater((half4)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((half4)(1747f)), maxmath.nextgreater((half4)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((half4)(-1747f)), maxmath.nextgreater((half4)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((half4)(1747f)), maxmath.nextgreater((half4)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((half4)(1747f)), maxmath.nextgreater((half4)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((half4)(-1747f)), maxmath.nextgreater((half4)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _half8() + { + Assert.AreEqual(maxmath.nextgreater((half8)(1747f)), maxmath.nextgreater((half8)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((half8)(1747f)), maxmath.nextgreater((half8)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((half8)(1747f)), maxmath.nextgreater((half8)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((half8)(-1747f)), maxmath.nextgreater((half8)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((half8)(1747f)), maxmath.nextgreater((half8)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((half8)(1747f)), maxmath.nextgreater((half8)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((half8)(-1747f)), maxmath.nextgreater((half8)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + + [Test] + public static void _float() + { + Assert.AreEqual(maxmath.nextgreater(1747f), maxmath.nextgreater(1747f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater(1747f), maxmath.nextgreater(1747f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater(1747f), maxmath.nextgreater(1747f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater(-1747f), maxmath.nextgreater(-1747f, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater(1747f), maxmath.nextgreater(1747f, maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater(1747f), maxmath.nextgreater(1747f, maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater(-1747f), maxmath.nextgreater(-1747f, maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _float2() + { + Assert.AreEqual(maxmath.nextgreater((float2)(1747f)), maxmath.nextgreater((float2)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((float2)(1747f)), maxmath.nextgreater((float2)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((float2)(1747f)), maxmath.nextgreater((float2)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((float2)(-1747f)), maxmath.nextgreater((float2)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((float2)(1747f)), maxmath.nextgreater((float2)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((float2)(1747f)), maxmath.nextgreater((float2)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((float2)(-1747f)), maxmath.nextgreater((float2)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _float3() + { + Assert.AreEqual(maxmath.nextgreater((float3)(1747f)), maxmath.nextgreater((float3)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((float3)(1747f)), maxmath.nextgreater((float3)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((float3)(1747f)), maxmath.nextgreater((float3)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((float3)(-1747f)), maxmath.nextgreater((float3)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((float3)(1747f)), maxmath.nextgreater((float3)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((float3)(1747f)), maxmath.nextgreater((float3)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((float3)(-1747f)), maxmath.nextgreater((float3)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _float4() + { + Assert.AreEqual(maxmath.nextgreater((float4)(1747f)), maxmath.nextgreater((float4)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((float4)(1747f)), maxmath.nextgreater((float4)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((float4)(1747f)), maxmath.nextgreater((float4)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((float4)(-1747f)), maxmath.nextgreater((float4)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((float4)(1747f)), maxmath.nextgreater((float4)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((float4)(1747f)), maxmath.nextgreater((float4)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((float4)(-1747f)), maxmath.nextgreater((float4)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _float8() + { + Assert.AreEqual(maxmath.nextgreater((float8)(1747f)), maxmath.nextgreater((float8)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((float8)(1747f)), maxmath.nextgreater((float8)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((float8)(1747f)), maxmath.nextgreater((float8)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((float8)(-1747f)), maxmath.nextgreater((float8)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((float8)(1747f)), maxmath.nextgreater((float8)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((float8)(1747f)), maxmath.nextgreater((float8)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((float8)(-1747f)), maxmath.nextgreater((float8)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + + [Test] + public static void _double() + { + Assert.AreEqual(maxmath.nextgreater(1747d), maxmath.nextgreater(1747d, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater(1747d), maxmath.nextgreater(1747d, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater(1747d), maxmath.nextgreater(1747d, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater(-1747d), maxmath.nextgreater(-1747d, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater(1747d), maxmath.nextgreater(1747d, maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater(1747d), maxmath.nextgreater(1747d, maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater(-1747d), maxmath.nextgreater(-1747d, maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _double2() + { + Assert.AreEqual(maxmath.nextgreater((double2)(1747d)), maxmath.nextgreater((double2)(1747d), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((double2)(1747d)), maxmath.nextgreater((double2)(1747d), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((double2)(1747d)), maxmath.nextgreater((double2)(1747d), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((double2)(-1747d)), maxmath.nextgreater((double2)(-1747d), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((double2)(1747d)), maxmath.nextgreater((double2)(1747d), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((double2)(1747d)), maxmath.nextgreater((double2)(1747d), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((double2)(-1747d)), maxmath.nextgreater((double2)(-1747d), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _double3() + { + Assert.AreEqual(maxmath.nextgreater((double3)(1747d)), maxmath.nextgreater((double3)(1747d), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((double3)(1747d)), maxmath.nextgreater((double3)(1747d), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((double3)(1747d)), maxmath.nextgreater((double3)(1747d), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((double3)(-1747d)), maxmath.nextgreater((double3)(-1747d), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((double3)(1747d)), maxmath.nextgreater((double3)(1747d), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((double3)(1747d)), maxmath.nextgreater((double3)(1747d), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((double3)(-1747d)), maxmath.nextgreater((double3)(-1747d), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _double4() + { + Assert.AreEqual(maxmath.nextgreater((double4)(1747d)), maxmath.nextgreater((double4)(1747d), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextgreater((double4)(1747d)), maxmath.nextgreater((double4)(1747d), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((double4)(1747d)), maxmath.nextgreater((double4)(1747d), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextgreater((double4)(-1747d)), maxmath.nextgreater((double4)(-1747d), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextgreater((double4)(1747d)), maxmath.nextgreater((double4)(1747d), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((double4)(1747d)), maxmath.nextgreater((double4)(1747d), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextgreater((double4)(-1747d)), maxmath.nextgreater((double4)(-1747d), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + } +} diff --git a/Tests/Editor/Functions/Promises/nextgreater.cs.meta b/Tests/Editor/Functions/Promises/nextgreater.cs.meta new file mode 100644 index 0000000..f13e93c --- /dev/null +++ b/Tests/Editor/Functions/Promises/nextgreater.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 23d82a41f7f1145459de384ac385ac61 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Editor/Functions/Promises/nextsmaller.cs b/Tests/Editor/Functions/Promises/nextsmaller.cs new file mode 100644 index 0000000..d5623b9 --- /dev/null +++ b/Tests/Editor/Functions/Promises/nextsmaller.cs @@ -0,0 +1,258 @@ +using NUnit.Framework; +using Unity.Mathematics; + +namespace MaxMath.Tests +{ + public static class PROMISE_nextsmaller + { + [Test] + public static void _quarter() + { + Assert.AreEqual(maxmath.nextsmaller((quarter)(1.747f)), maxmath.nextsmaller((quarter)(1.747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((quarter)(1.747f)), maxmath.nextsmaller((quarter)(1.747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((quarter)(1.747f)), maxmath.nextsmaller((quarter)(1.747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((quarter)(-1.747f)), maxmath.nextsmaller((quarter)(-1.747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((quarter)(1.747f)), maxmath.nextsmaller((quarter)(1.747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((quarter)(1.747f)), maxmath.nextsmaller((quarter)(1.747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((quarter)(-1.747f)), maxmath.nextsmaller((quarter)(-1.747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _quarter2() + { + Assert.AreEqual(maxmath.nextsmaller((quarter2)(1.747f)), maxmath.nextsmaller((quarter2)(1.747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((quarter2)(1.747f)), maxmath.nextsmaller((quarter2)(1.747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((quarter2)(1.747f)), maxmath.nextsmaller((quarter2)(1.747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((quarter2)(-1.747f)), maxmath.nextsmaller((quarter2)(-1.747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((quarter2)(1.747f)), maxmath.nextsmaller((quarter2)(1.747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((quarter2)(1.747f)), maxmath.nextsmaller((quarter2)(1.747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((quarter2)(-1.747f)), maxmath.nextsmaller((quarter2)(-1.747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _quarter3() + { + Assert.AreEqual(maxmath.nextsmaller((quarter3)(1.747f)), maxmath.nextsmaller((quarter3)(1.747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((quarter3)(1.747f)), maxmath.nextsmaller((quarter3)(1.747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((quarter3)(1.747f)), maxmath.nextsmaller((quarter3)(1.747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((quarter3)(-1.747f)), maxmath.nextsmaller((quarter3)(-1.747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((quarter3)(1.747f)), maxmath.nextsmaller((quarter3)(1.747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((quarter3)(1.747f)), maxmath.nextsmaller((quarter3)(1.747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((quarter3)(-1.747f)), maxmath.nextsmaller((quarter3)(-1.747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _quarter4() + { + Assert.AreEqual(maxmath.nextsmaller((quarter4)(1.747f)), maxmath.nextsmaller((quarter4)(1.747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((quarter4)(1.747f)), maxmath.nextsmaller((quarter4)(1.747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((quarter4)(1.747f)), maxmath.nextsmaller((quarter4)(1.747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((quarter4)(-1.747f)), maxmath.nextsmaller((quarter4)(-1.747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((quarter4)(1.747f)), maxmath.nextsmaller((quarter4)(1.747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((quarter4)(1.747f)), maxmath.nextsmaller((quarter4)(1.747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((quarter4)(-1.747f)), maxmath.nextsmaller((quarter4)(-1.747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _quarter8() + { + Assert.AreEqual(maxmath.nextsmaller((quarter8)(1.747f)), maxmath.nextsmaller((quarter8)(1.747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((quarter8)(1.747f)), maxmath.nextsmaller((quarter8)(1.747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((quarter8)(1.747f)), maxmath.nextsmaller((quarter8)(1.747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((quarter8)(-1.747f)), maxmath.nextsmaller((quarter8)(-1.747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((quarter8)(1.747f)), maxmath.nextsmaller((quarter8)(1.747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((quarter8)(1.747f)), maxmath.nextsmaller((quarter8)(1.747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((quarter8)(-1.747f)), maxmath.nextsmaller((quarter8)(-1.747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + + [Test] + public static void _half() + { + Assert.AreEqual(maxmath.nextsmaller((half)(1747f)), maxmath.nextsmaller((half)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((half)(1747f)), maxmath.nextsmaller((half)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((half)(1747f)), maxmath.nextsmaller((half)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((half)(-1747f)), maxmath.nextsmaller((half)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((half)(1747f)), maxmath.nextsmaller((half)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((half)(1747f)), maxmath.nextsmaller((half)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((half)(-1747f)), maxmath.nextsmaller((half)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _half2() + { + Assert.AreEqual(maxmath.nextsmaller((half2)(1747f)), maxmath.nextsmaller((half2)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((half2)(1747f)), maxmath.nextsmaller((half2)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((half2)(1747f)), maxmath.nextsmaller((half2)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((half2)(-1747f)), maxmath.nextsmaller((half2)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((half2)(1747f)), maxmath.nextsmaller((half2)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((half2)(1747f)), maxmath.nextsmaller((half2)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((half2)(-1747f)), maxmath.nextsmaller((half2)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _half3() + { + Assert.AreEqual(maxmath.nextsmaller((half3)(1747f)), maxmath.nextsmaller((half3)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((half3)(1747f)), maxmath.nextsmaller((half3)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((half3)(1747f)), maxmath.nextsmaller((half3)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((half3)(-1747f)), maxmath.nextsmaller((half3)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((half3)(1747f)), maxmath.nextsmaller((half3)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((half3)(1747f)), maxmath.nextsmaller((half3)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((half3)(-1747f)), maxmath.nextsmaller((half3)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _half4() + { + Assert.AreEqual(maxmath.nextsmaller((half4)(1747f)), maxmath.nextsmaller((half4)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((half4)(1747f)), maxmath.nextsmaller((half4)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((half4)(1747f)), maxmath.nextsmaller((half4)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((half4)(-1747f)), maxmath.nextsmaller((half4)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((half4)(1747f)), maxmath.nextsmaller((half4)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((half4)(1747f)), maxmath.nextsmaller((half4)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((half4)(-1747f)), maxmath.nextsmaller((half4)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _half8() + { + Assert.AreEqual(maxmath.nextsmaller((half8)(1747f)), maxmath.nextsmaller((half8)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((half8)(1747f)), maxmath.nextsmaller((half8)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((half8)(1747f)), maxmath.nextsmaller((half8)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((half8)(-1747f)), maxmath.nextsmaller((half8)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((half8)(1747f)), maxmath.nextsmaller((half8)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((half8)(1747f)), maxmath.nextsmaller((half8)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((half8)(-1747f)), maxmath.nextsmaller((half8)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + + [Test] + public static void _float() + { + Assert.AreEqual(maxmath.nextsmaller(1747f), maxmath.nextsmaller(1747f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller(1747f), maxmath.nextsmaller(1747f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller(1747f), maxmath.nextsmaller(1747f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller(-1747f), maxmath.nextsmaller(-1747f, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller(1747f), maxmath.nextsmaller(1747f, maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller(1747f), maxmath.nextsmaller(1747f, maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller(-1747f), maxmath.nextsmaller(-1747f, maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _float2() + { + Assert.AreEqual(maxmath.nextsmaller((float2)(1747f)), maxmath.nextsmaller((float2)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((float2)(1747f)), maxmath.nextsmaller((float2)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((float2)(1747f)), maxmath.nextsmaller((float2)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((float2)(-1747f)), maxmath.nextsmaller((float2)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((float2)(1747f)), maxmath.nextsmaller((float2)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((float2)(1747f)), maxmath.nextsmaller((float2)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((float2)(-1747f)), maxmath.nextsmaller((float2)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _float3() + { + Assert.AreEqual(maxmath.nextsmaller((float3)(1747f)), maxmath.nextsmaller((float3)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((float3)(1747f)), maxmath.nextsmaller((float3)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((float3)(1747f)), maxmath.nextsmaller((float3)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((float3)(-1747f)), maxmath.nextsmaller((float3)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((float3)(1747f)), maxmath.nextsmaller((float3)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((float3)(1747f)), maxmath.nextsmaller((float3)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((float3)(-1747f)), maxmath.nextsmaller((float3)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _float4() + { + Assert.AreEqual(maxmath.nextsmaller((float4)(1747f)), maxmath.nextsmaller((float4)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((float4)(1747f)), maxmath.nextsmaller((float4)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((float4)(1747f)), maxmath.nextsmaller((float4)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((float4)(-1747f)), maxmath.nextsmaller((float4)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((float4)(1747f)), maxmath.nextsmaller((float4)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((float4)(1747f)), maxmath.nextsmaller((float4)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((float4)(-1747f)), maxmath.nextsmaller((float4)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _float8() + { + Assert.AreEqual(maxmath.nextsmaller((float8)(1747f)), maxmath.nextsmaller((float8)(1747f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((float8)(1747f)), maxmath.nextsmaller((float8)(1747f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((float8)(1747f)), maxmath.nextsmaller((float8)(1747f), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((float8)(-1747f)), maxmath.nextsmaller((float8)(-1747f), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((float8)(1747f)), maxmath.nextsmaller((float8)(1747f), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((float8)(1747f)), maxmath.nextsmaller((float8)(1747f), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((float8)(-1747f)), maxmath.nextsmaller((float8)(-1747f), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + + [Test] + public static void _double() + { + Assert.AreEqual(maxmath.nextsmaller(1747d), maxmath.nextsmaller(1747d, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller(1747d), maxmath.nextsmaller(1747d, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller(1747d), maxmath.nextsmaller(1747d, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller(-1747d), maxmath.nextsmaller(-1747d, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller(1747d), maxmath.nextsmaller(1747d, maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller(1747d), maxmath.nextsmaller(1747d, maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller(-1747d), maxmath.nextsmaller(-1747d, maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _double2() + { + Assert.AreEqual(maxmath.nextsmaller((double2)(1747d)), maxmath.nextsmaller((double2)(1747d), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((double2)(1747d)), maxmath.nextsmaller((double2)(1747d), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((double2)(1747d)), maxmath.nextsmaller((double2)(1747d), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((double2)(-1747d)), maxmath.nextsmaller((double2)(-1747d), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((double2)(1747d)), maxmath.nextsmaller((double2)(1747d), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((double2)(1747d)), maxmath.nextsmaller((double2)(1747d), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((double2)(-1747d)), maxmath.nextsmaller((double2)(-1747d), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _double3() + { + Assert.AreEqual(maxmath.nextsmaller((double3)(1747d)), maxmath.nextsmaller((double3)(1747d), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((double3)(1747d)), maxmath.nextsmaller((double3)(1747d), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((double3)(1747d)), maxmath.nextsmaller((double3)(1747d), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((double3)(-1747d)), maxmath.nextsmaller((double3)(-1747d), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((double3)(1747d)), maxmath.nextsmaller((double3)(1747d), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((double3)(1747d)), maxmath.nextsmaller((double3)(1747d), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((double3)(-1747d)), maxmath.nextsmaller((double3)(-1747d), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + + [Test] + public static void _double4() + { + Assert.AreEqual(maxmath.nextsmaller((double4)(1747d)), maxmath.nextsmaller((double4)(1747d), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nextsmaller((double4)(1747d)), maxmath.nextsmaller((double4)(1747d), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((double4)(1747d)), maxmath.nextsmaller((double4)(1747d), maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nextsmaller((double4)(-1747d)), maxmath.nextsmaller((double4)(-1747d), maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nextsmaller((double4)(1747d)), maxmath.nextsmaller((double4)(1747d), maxmath.Promise.NonZero | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((double4)(1747d)), maxmath.nextsmaller((double4)(1747d), maxmath.Promise.Positive | maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nextsmaller((double4)(-1747d)), maxmath.nextsmaller((double4)(-1747d), maxmath.Promise.Negative | maxmath.Promise.Unsafe0)); + } + } +} diff --git a/Tests/Editor/Functions/Promises/nextsmaller.cs.meta b/Tests/Editor/Functions/Promises/nextsmaller.cs.meta new file mode 100644 index 0000000..5d885cc --- /dev/null +++ b/Tests/Editor/Functions/Promises/nextsmaller.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4111780d4040567479a66f734127cbf4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Editor/Functions/Promises/nexttoward.cs b/Tests/Editor/Functions/Promises/nexttoward.cs new file mode 100644 index 0000000..183ea4d --- /dev/null +++ b/Tests/Editor/Functions/Promises/nexttoward.cs @@ -0,0 +1,923 @@ +using NUnit.Framework; +using Unity.Mathematics; + +namespace MaxMath.Tests +{ + public static class PROMISE_nexttoward + { + [Test] + public static void _quarter() + { + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)float.PositiveInfinity), maxmath.nexttoward((quarter)1.747f, (quarter)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)0f), maxmath.nexttoward((quarter)1.747f, (quarter)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)1.748f), maxmath.nexttoward((quarter)1.747f, (quarter)1.748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)1.746f), maxmath.nexttoward((quarter)1.747f, (quarter)1.746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)float.NegativeInfinity), maxmath.nexttoward((quarter)1.747f, (quarter)float.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)float.PositiveInfinity), maxmath.nexttoward((quarter)(-1.747f), (quarter)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)0f), maxmath.nexttoward((quarter)(-1.747f), (quarter)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)(-1.748f)), maxmath.nexttoward((quarter)(-1.747f), (quarter)(-1.748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)(-1.746f)), maxmath.nexttoward((quarter)(-1.747f), (quarter)(-1.746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)float.NegativeInfinity), maxmath.nexttoward((quarter)(-1.747f), (quarter)float.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)float.PositiveInfinity), maxmath.nexttoward((quarter)1.747f, (quarter)float.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)0f), maxmath.nexttoward((quarter)1.747f, (quarter)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)1.748f), maxmath.nexttoward((quarter)1.747f, (quarter)1.748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)1.746f), maxmath.nexttoward((quarter)1.747f, (quarter)1.746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)float.NegativeInfinity), maxmath.nexttoward((quarter)1.747f, (quarter)float.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)float.PositiveInfinity), maxmath.nexttoward((quarter)(-1.747f), (quarter)float.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)0f), maxmath.nexttoward((quarter)(-1.747f), (quarter)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)(-1.748f)), maxmath.nexttoward((quarter)(-1.747f), (quarter)(-1.748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)(-1.746f)), maxmath.nexttoward((quarter)(-1.747f), (quarter)(-1.746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)float.NegativeInfinity), maxmath.nexttoward((quarter)(-1.747f), (quarter)float.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)float.PositiveInfinity), maxmath.nexttoward((quarter)1.747f, (quarter)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)0f), maxmath.nexttoward((quarter)1.747f, (quarter)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)1.748f), maxmath.nexttoward((quarter)1.747f, (quarter)1.748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)1.746f), maxmath.nexttoward((quarter)1.747f, (quarter)1.746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)float.NegativeInfinity), maxmath.nexttoward((quarter)1.747f, (quarter)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)float.PositiveInfinity), maxmath.nexttoward((quarter)(-1.747f), (quarter)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)0f), maxmath.nexttoward((quarter)(-1.747f), (quarter)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)(-1.748f)), maxmath.nexttoward((quarter)(-1.747f), (quarter)(-1.748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)(-1.746f)), maxmath.nexttoward((quarter)(-1.747f), (quarter)(-1.746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)float.NegativeInfinity), maxmath.nexttoward((quarter)(-1.747f), (quarter)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)float.PositiveInfinity), maxmath.nexttoward((quarter)1.747f, (quarter)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)0f), maxmath.nexttoward((quarter)1.747f, (quarter)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)1.748f), maxmath.nexttoward((quarter)1.747f, (quarter)1.748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)1.746f), maxmath.nexttoward((quarter)1.747f, (quarter)1.746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter)1.747f, (quarter)float.NegativeInfinity), maxmath.nexttoward((quarter)1.747f, (quarter)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)float.PositiveInfinity), maxmath.nexttoward((quarter)(-1.747f), (quarter)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)0f), maxmath.nexttoward((quarter)(-1.747f), (quarter)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)(-1.748f)), maxmath.nexttoward((quarter)(-1.747f), (quarter)(-1.748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)(-1.746f)), maxmath.nexttoward((quarter)(-1.747f), (quarter)(-1.746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter)(-1.747f), (quarter)float.NegativeInfinity), maxmath.nexttoward((quarter)(-1.747f), (quarter)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + [Test] + public static void _quarter2() + { + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)float.PositiveInfinity), maxmath.nexttoward((quarter2)1.747f, (quarter2)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)0f), maxmath.nexttoward((quarter2)1.747f, (quarter2)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)1.748f), maxmath.nexttoward((quarter2)1.747f, (quarter2)1.748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)1.746f), maxmath.nexttoward((quarter2)1.747f, (quarter2)1.746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)float.NegativeInfinity), maxmath.nexttoward((quarter2)1.747f, (quarter2)float.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)float.PositiveInfinity), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)0f), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)(-1.748f)), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)(-1.748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)(-1.746f)), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)(-1.746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)float.NegativeInfinity), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)float.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)float.PositiveInfinity), maxmath.nexttoward((quarter2)1.747f, (quarter2)float.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)0f), maxmath.nexttoward((quarter2)1.747f, (quarter2)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)1.748f), maxmath.nexttoward((quarter2)1.747f, (quarter2)1.748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)1.746f), maxmath.nexttoward((quarter2)1.747f, (quarter2)1.746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)float.NegativeInfinity), maxmath.nexttoward((quarter2)1.747f, (quarter2)float.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)float.PositiveInfinity), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)float.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)0f), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)(-1.748f)), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)(-1.748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)(-1.746f)), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)(-1.746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)float.NegativeInfinity), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)float.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)float.PositiveInfinity), maxmath.nexttoward((quarter2)1.747f, (quarter2)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)0f), maxmath.nexttoward((quarter2)1.747f, (quarter2)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)1.748f), maxmath.nexttoward((quarter2)1.747f, (quarter2)1.748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)1.746f), maxmath.nexttoward((quarter2)1.747f, (quarter2)1.746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)float.NegativeInfinity), maxmath.nexttoward((quarter2)1.747f, (quarter2)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)float.PositiveInfinity), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)0f), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)(-1.748f)), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)(-1.748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)(-1.746f)), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)(-1.746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)float.NegativeInfinity), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)float.PositiveInfinity), maxmath.nexttoward((quarter2)1.747f, (quarter2)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)0f), maxmath.nexttoward((quarter2)1.747f, (quarter2)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)1.748f), maxmath.nexttoward((quarter2)1.747f, (quarter2)1.748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)1.746f), maxmath.nexttoward((quarter2)1.747f, (quarter2)1.746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter2)1.747f, (quarter2)float.NegativeInfinity), maxmath.nexttoward((quarter2)1.747f, (quarter2)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)float.PositiveInfinity), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)0f), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)(-1.748f)), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)(-1.748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)(-1.746f)), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)(-1.746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter2)(-1.747f), (quarter2)float.NegativeInfinity), maxmath.nexttoward((quarter2)(-1.747f), (quarter2)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + [Test] + public static void _quarter3() + { + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)float.PositiveInfinity), maxmath.nexttoward((quarter3)1.747f, (quarter3)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)0f), maxmath.nexttoward((quarter3)1.747f, (quarter3)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)1.748f), maxmath.nexttoward((quarter3)1.747f, (quarter3)1.748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)1.746f), maxmath.nexttoward((quarter3)1.747f, (quarter3)1.746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)float.NegativeInfinity), maxmath.nexttoward((quarter3)1.747f, (quarter3)float.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)float.PositiveInfinity), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)0f), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)(-1.748f)), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)(-1.748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)(-1.746f)), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)(-1.746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)float.NegativeInfinity), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)float.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)float.PositiveInfinity), maxmath.nexttoward((quarter3)1.747f, (quarter3)float.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)0f), maxmath.nexttoward((quarter3)1.747f, (quarter3)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)1.748f), maxmath.nexttoward((quarter3)1.747f, (quarter3)1.748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)1.746f), maxmath.nexttoward((quarter3)1.747f, (quarter3)1.746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)float.NegativeInfinity), maxmath.nexttoward((quarter3)1.747f, (quarter3)float.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)float.PositiveInfinity), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)float.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)0f), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)(-1.748f)), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)(-1.748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)(-1.746f)), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)(-1.746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)float.NegativeInfinity), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)float.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)float.PositiveInfinity), maxmath.nexttoward((quarter3)1.747f, (quarter3)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)0f), maxmath.nexttoward((quarter3)1.747f, (quarter3)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)1.748f), maxmath.nexttoward((quarter3)1.747f, (quarter3)1.748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)1.746f), maxmath.nexttoward((quarter3)1.747f, (quarter3)1.746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)float.NegativeInfinity), maxmath.nexttoward((quarter3)1.747f, (quarter3)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)float.PositiveInfinity), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)0f), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)(-1.748f)), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)(-1.748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)(-1.746f)), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)(-1.746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)float.NegativeInfinity), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)float.PositiveInfinity), maxmath.nexttoward((quarter3)1.747f, (quarter3)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)0f), maxmath.nexttoward((quarter3)1.747f, (quarter3)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)1.748f), maxmath.nexttoward((quarter3)1.747f, (quarter3)1.748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)1.746f), maxmath.nexttoward((quarter3)1.747f, (quarter3)1.746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter3)1.747f, (quarter3)float.NegativeInfinity), maxmath.nexttoward((quarter3)1.747f, (quarter3)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)float.PositiveInfinity), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)0f), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)(-1.748f)), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)(-1.748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)(-1.746f)), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)(-1.746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter3)(-1.747f), (quarter3)float.NegativeInfinity), maxmath.nexttoward((quarter3)(-1.747f), (quarter3)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + [Test] + public static void _quarter4() + { + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)float.PositiveInfinity), maxmath.nexttoward((quarter4)1.747f, (quarter4)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)0f), maxmath.nexttoward((quarter4)1.747f, (quarter4)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)1.748f), maxmath.nexttoward((quarter4)1.747f, (quarter4)1.748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)1.746f), maxmath.nexttoward((quarter4)1.747f, (quarter4)1.746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)float.NegativeInfinity), maxmath.nexttoward((quarter4)1.747f, (quarter4)float.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)float.PositiveInfinity), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)0f), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)(-1.748f)), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)(-1.748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)(-1.746f)), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)(-1.746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)float.NegativeInfinity), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)float.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)float.PositiveInfinity), maxmath.nexttoward((quarter4)1.747f, (quarter4)float.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)0f), maxmath.nexttoward((quarter4)1.747f, (quarter4)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)1.748f), maxmath.nexttoward((quarter4)1.747f, (quarter4)1.748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)1.746f), maxmath.nexttoward((quarter4)1.747f, (quarter4)1.746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)float.NegativeInfinity), maxmath.nexttoward((quarter4)1.747f, (quarter4)float.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)float.PositiveInfinity), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)float.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)0f), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)(-1.748f)), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)(-1.748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)(-1.746f)), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)(-1.746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)float.NegativeInfinity), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)float.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)float.PositiveInfinity), maxmath.nexttoward((quarter4)1.747f, (quarter4)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)0f), maxmath.nexttoward((quarter4)1.747f, (quarter4)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)1.748f), maxmath.nexttoward((quarter4)1.747f, (quarter4)1.748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)1.746f), maxmath.nexttoward((quarter4)1.747f, (quarter4)1.746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)float.NegativeInfinity), maxmath.nexttoward((quarter4)1.747f, (quarter4)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)float.PositiveInfinity), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)0f), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)(-1.748f)), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)(-1.748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)(-1.746f)), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)(-1.746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)float.NegativeInfinity), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)float.PositiveInfinity), maxmath.nexttoward((quarter4)1.747f, (quarter4)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)0f), maxmath.nexttoward((quarter4)1.747f, (quarter4)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)1.748f), maxmath.nexttoward((quarter4)1.747f, (quarter4)1.748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)1.746f), maxmath.nexttoward((quarter4)1.747f, (quarter4)1.746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter4)1.747f, (quarter4)float.NegativeInfinity), maxmath.nexttoward((quarter4)1.747f, (quarter4)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)float.PositiveInfinity), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)0f), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)(-1.748f)), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)(-1.748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)(-1.746f)), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)(-1.746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter4)(-1.747f), (quarter4)float.NegativeInfinity), maxmath.nexttoward((quarter4)(-1.747f), (quarter4)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + [Test] + public static void _quarter8() + { + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)float.PositiveInfinity), maxmath.nexttoward((quarter8)1.747f, (quarter8)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)0f), maxmath.nexttoward((quarter8)1.747f, (quarter8)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)1.748f), maxmath.nexttoward((quarter8)1.747f, (quarter8)1.748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)1.746f), maxmath.nexttoward((quarter8)1.747f, (quarter8)1.746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)float.NegativeInfinity), maxmath.nexttoward((quarter8)1.747f, (quarter8)float.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)float.PositiveInfinity), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)0f), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)(-1.748f)), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)(-1.748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)(-1.746f)), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)(-1.746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)float.NegativeInfinity), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)float.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)float.PositiveInfinity), maxmath.nexttoward((quarter8)1.747f, (quarter8)float.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)0f), maxmath.nexttoward((quarter8)1.747f, (quarter8)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)1.748f), maxmath.nexttoward((quarter8)1.747f, (quarter8)1.748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)1.746f), maxmath.nexttoward((quarter8)1.747f, (quarter8)1.746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)float.NegativeInfinity), maxmath.nexttoward((quarter8)1.747f, (quarter8)float.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)float.PositiveInfinity), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)float.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)0f), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)(-1.748f)), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)(-1.748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)(-1.746f)), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)(-1.746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)float.NegativeInfinity), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)float.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)float.PositiveInfinity), maxmath.nexttoward((quarter8)1.747f, (quarter8)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)0f), maxmath.nexttoward((quarter8)1.747f, (quarter8)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)1.748f), maxmath.nexttoward((quarter8)1.747f, (quarter8)1.748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)1.746f), maxmath.nexttoward((quarter8)1.747f, (quarter8)1.746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)float.NegativeInfinity), maxmath.nexttoward((quarter8)1.747f, (quarter8)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)float.PositiveInfinity), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)0f), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)(-1.748f)), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)(-1.748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)(-1.746f)), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)(-1.746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)float.NegativeInfinity), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)float.PositiveInfinity), maxmath.nexttoward((quarter8)1.747f, (quarter8)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)0f), maxmath.nexttoward((quarter8)1.747f, (quarter8)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)1.748f), maxmath.nexttoward((quarter8)1.747f, (quarter8)1.748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)1.746f), maxmath.nexttoward((quarter8)1.747f, (quarter8)1.746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter8)1.747f, (quarter8)float.NegativeInfinity), maxmath.nexttoward((quarter8)1.747f, (quarter8)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)float.PositiveInfinity), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)0f), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)(-1.748f)), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)(-1.748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)(-1.746f)), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)(-1.746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((quarter8)(-1.747f), (quarter8)float.NegativeInfinity), maxmath.nexttoward((quarter8)(-1.747f), (quarter8)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + + [Test] + public static void _half() + { + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)float.PositiveInfinity), maxmath.nexttoward((half)1747f, (half)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)0f), maxmath.nexttoward((half)1747f, (half)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)1748f), maxmath.nexttoward((half)1747f, (half)1748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)1746f), maxmath.nexttoward((half)1747f, (half)1746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)float.NegativeInfinity), maxmath.nexttoward((half)1747f, (half)float.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)float.PositiveInfinity), maxmath.nexttoward((half)(-1747f), (half)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)0f), maxmath.nexttoward((half)(-1747f), (half)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)(-1748f)), maxmath.nexttoward((half)(-1747f), (half)(-1748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)(-1746f)), maxmath.nexttoward((half)(-1747f), (half)(-1746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)float.NegativeInfinity), maxmath.nexttoward((half)(-1747f), (half)float.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)float.PositiveInfinity), maxmath.nexttoward((half)1747f, (half)float.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)0f), maxmath.nexttoward((half)1747f, (half)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)1748f), maxmath.nexttoward((half)1747f, (half)1748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)1746f), maxmath.nexttoward((half)1747f, (half)1746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)float.NegativeInfinity), maxmath.nexttoward((half)1747f, (half)float.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)float.PositiveInfinity), maxmath.nexttoward((half)(-1747f), (half)float.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)0f), maxmath.nexttoward((half)(-1747f), (half)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)(-1748f)), maxmath.nexttoward((half)(-1747f), (half)(-1748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)(-1746f)), maxmath.nexttoward((half)(-1747f), (half)(-1746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)float.NegativeInfinity), maxmath.nexttoward((half)(-1747f), (half)float.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)float.PositiveInfinity), maxmath.nexttoward((half)1747f, (half)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)0f), maxmath.nexttoward((half)1747f, (half)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)1748f), maxmath.nexttoward((half)1747f, (half)1748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)1746f), maxmath.nexttoward((half)1747f, (half)1746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)float.NegativeInfinity), maxmath.nexttoward((half)1747f, (half)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)float.PositiveInfinity), maxmath.nexttoward((half)(-1747f), (half)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)0f), maxmath.nexttoward((half)(-1747f), (half)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)(-1748f)), maxmath.nexttoward((half)(-1747f), (half)(-1748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)(-1746f)), maxmath.nexttoward((half)(-1747f), (half)(-1746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)float.NegativeInfinity), maxmath.nexttoward((half)(-1747f), (half)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)float.PositiveInfinity), maxmath.nexttoward((half)1747f, (half)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)0f), maxmath.nexttoward((half)1747f, (half)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)1748f), maxmath.nexttoward((half)1747f, (half)1748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)1746f), maxmath.nexttoward((half)1747f, (half)1746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half)1747f, (half)float.NegativeInfinity), maxmath.nexttoward((half)1747f, (half)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)float.PositiveInfinity), maxmath.nexttoward((half)(-1747f), (half)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)0f), maxmath.nexttoward((half)(-1747f), (half)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)(-1748f)), maxmath.nexttoward((half)(-1747f), (half)(-1748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)(-1746f)), maxmath.nexttoward((half)(-1747f), (half)(-1746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half)(-1747f), (half)float.NegativeInfinity), maxmath.nexttoward((half)(-1747f), (half)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + [Test] + public static void _half2() + { + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)float.PositiveInfinity), maxmath.nexttoward((half2)1747f, (half2)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)0f), maxmath.nexttoward((half2)1747f, (half2)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)1748f), maxmath.nexttoward((half2)1747f, (half2)1748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)1746f), maxmath.nexttoward((half2)1747f, (half2)1746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)float.NegativeInfinity), maxmath.nexttoward((half2)1747f, (half2)float.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)float.PositiveInfinity), maxmath.nexttoward((half2)(-1747f), (half2)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)0f), maxmath.nexttoward((half2)(-1747f), (half2)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)(-1748f)), maxmath.nexttoward((half2)(-1747f), (half2)(-1748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)(-1746f)), maxmath.nexttoward((half2)(-1747f), (half2)(-1746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)float.NegativeInfinity), maxmath.nexttoward((half2)(-1747f), (half2)float.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)float.PositiveInfinity), maxmath.nexttoward((half2)1747f, (half2)float.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)0f), maxmath.nexttoward((half2)1747f, (half2)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)1748f), maxmath.nexttoward((half2)1747f, (half2)1748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)1746f), maxmath.nexttoward((half2)1747f, (half2)1746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)float.NegativeInfinity), maxmath.nexttoward((half2)1747f, (half2)float.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)float.PositiveInfinity), maxmath.nexttoward((half2)(-1747f), (half2)float.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)0f), maxmath.nexttoward((half2)(-1747f), (half2)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)(-1748f)), maxmath.nexttoward((half2)(-1747f), (half2)(-1748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)(-1746f)), maxmath.nexttoward((half2)(-1747f), (half2)(-1746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)float.NegativeInfinity), maxmath.nexttoward((half2)(-1747f), (half2)float.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)float.PositiveInfinity), maxmath.nexttoward((half2)1747f, (half2)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)0f), maxmath.nexttoward((half2)1747f, (half2)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)1748f), maxmath.nexttoward((half2)1747f, (half2)1748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)1746f), maxmath.nexttoward((half2)1747f, (half2)1746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)float.NegativeInfinity), maxmath.nexttoward((half2)1747f, (half2)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)float.PositiveInfinity), maxmath.nexttoward((half2)(-1747f), (half2)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)0f), maxmath.nexttoward((half2)(-1747f), (half2)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)(-1748f)), maxmath.nexttoward((half2)(-1747f), (half2)(-1748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)(-1746f)), maxmath.nexttoward((half2)(-1747f), (half2)(-1746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)float.NegativeInfinity), maxmath.nexttoward((half2)(-1747f), (half2)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)float.PositiveInfinity), maxmath.nexttoward((half2)1747f, (half2)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)0f), maxmath.nexttoward((half2)1747f, (half2)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)1748f), maxmath.nexttoward((half2)1747f, (half2)1748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)1746f), maxmath.nexttoward((half2)1747f, (half2)1746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half2)1747f, (half2)float.NegativeInfinity), maxmath.nexttoward((half2)1747f, (half2)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)float.PositiveInfinity), maxmath.nexttoward((half2)(-1747f), (half2)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)0f), maxmath.nexttoward((half2)(-1747f), (half2)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)(-1748f)), maxmath.nexttoward((half2)(-1747f), (half2)(-1748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)(-1746f)), maxmath.nexttoward((half2)(-1747f), (half2)(-1746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half2)(-1747f), (half2)float.NegativeInfinity), maxmath.nexttoward((half2)(-1747f), (half2)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + [Test] + public static void _half3() + { + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)float.PositiveInfinity), maxmath.nexttoward((half3)1747f, (half3)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)0f), maxmath.nexttoward((half3)1747f, (half3)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)1748f), maxmath.nexttoward((half3)1747f, (half3)1748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)1746f), maxmath.nexttoward((half3)1747f, (half3)1746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)float.NegativeInfinity), maxmath.nexttoward((half3)1747f, (half3)float.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)float.PositiveInfinity), maxmath.nexttoward((half3)(-1747f), (half3)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)0f), maxmath.nexttoward((half3)(-1747f), (half3)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)(-1748f)), maxmath.nexttoward((half3)(-1747f), (half3)(-1748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)(-1746f)), maxmath.nexttoward((half3)(-1747f), (half3)(-1746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)float.NegativeInfinity), maxmath.nexttoward((half3)(-1747f), (half3)float.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)float.PositiveInfinity), maxmath.nexttoward((half3)1747f, (half3)float.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)0f), maxmath.nexttoward((half3)1747f, (half3)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)1748f), maxmath.nexttoward((half3)1747f, (half3)1748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)1746f), maxmath.nexttoward((half3)1747f, (half3)1746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)float.NegativeInfinity), maxmath.nexttoward((half3)1747f, (half3)float.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)float.PositiveInfinity), maxmath.nexttoward((half3)(-1747f), (half3)float.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)0f), maxmath.nexttoward((half3)(-1747f), (half3)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)(-1748f)), maxmath.nexttoward((half3)(-1747f), (half3)(-1748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)(-1746f)), maxmath.nexttoward((half3)(-1747f), (half3)(-1746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)float.NegativeInfinity), maxmath.nexttoward((half3)(-1747f), (half3)float.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)float.PositiveInfinity), maxmath.nexttoward((half3)1747f, (half3)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)0f), maxmath.nexttoward((half3)1747f, (half3)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)1748f), maxmath.nexttoward((half3)1747f, (half3)1748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)1746f), maxmath.nexttoward((half3)1747f, (half3)1746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)float.NegativeInfinity), maxmath.nexttoward((half3)1747f, (half3)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)float.PositiveInfinity), maxmath.nexttoward((half3)(-1747f), (half3)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)0f), maxmath.nexttoward((half3)(-1747f), (half3)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)(-1748f)), maxmath.nexttoward((half3)(-1747f), (half3)(-1748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)(-1746f)), maxmath.nexttoward((half3)(-1747f), (half3)(-1746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)float.NegativeInfinity), maxmath.nexttoward((half3)(-1747f), (half3)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)float.PositiveInfinity), maxmath.nexttoward((half3)1747f, (half3)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)0f), maxmath.nexttoward((half3)1747f, (half3)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)1748f), maxmath.nexttoward((half3)1747f, (half3)1748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)1746f), maxmath.nexttoward((half3)1747f, (half3)1746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half3)1747f, (half3)float.NegativeInfinity), maxmath.nexttoward((half3)1747f, (half3)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)float.PositiveInfinity), maxmath.nexttoward((half3)(-1747f), (half3)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)0f), maxmath.nexttoward((half3)(-1747f), (half3)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)(-1748f)), maxmath.nexttoward((half3)(-1747f), (half3)(-1748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)(-1746f)), maxmath.nexttoward((half3)(-1747f), (half3)(-1746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half3)(-1747f), (half3)float.NegativeInfinity), maxmath.nexttoward((half3)(-1747f), (half3)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + [Test] + public static void _half4() + { + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)float.PositiveInfinity), maxmath.nexttoward((half4)1747f, (half4)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)0f), maxmath.nexttoward((half4)1747f, (half4)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)1748f), maxmath.nexttoward((half4)1747f, (half4)1748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)1746f), maxmath.nexttoward((half4)1747f, (half4)1746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)float.NegativeInfinity), maxmath.nexttoward((half4)1747f, (half4)float.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)float.PositiveInfinity), maxmath.nexttoward((half4)(-1747f), (half4)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)0f), maxmath.nexttoward((half4)(-1747f), (half4)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)(-1748f)), maxmath.nexttoward((half4)(-1747f), (half4)(-1748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)(-1746f)), maxmath.nexttoward((half4)(-1747f), (half4)(-1746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)float.NegativeInfinity), maxmath.nexttoward((half4)(-1747f), (half4)float.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)float.PositiveInfinity), maxmath.nexttoward((half4)1747f, (half4)float.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)0f), maxmath.nexttoward((half4)1747f, (half4)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)1748f), maxmath.nexttoward((half4)1747f, (half4)1748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)1746f), maxmath.nexttoward((half4)1747f, (half4)1746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)float.NegativeInfinity), maxmath.nexttoward((half4)1747f, (half4)float.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)float.PositiveInfinity), maxmath.nexttoward((half4)(-1747f), (half4)float.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)0f), maxmath.nexttoward((half4)(-1747f), (half4)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)(-1748f)), maxmath.nexttoward((half4)(-1747f), (half4)(-1748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)(-1746f)), maxmath.nexttoward((half4)(-1747f), (half4)(-1746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)float.NegativeInfinity), maxmath.nexttoward((half4)(-1747f), (half4)float.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)float.PositiveInfinity), maxmath.nexttoward((half4)1747f, (half4)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)0f), maxmath.nexttoward((half4)1747f, (half4)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)1748f), maxmath.nexttoward((half4)1747f, (half4)1748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)1746f), maxmath.nexttoward((half4)1747f, (half4)1746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)float.NegativeInfinity), maxmath.nexttoward((half4)1747f, (half4)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)float.PositiveInfinity), maxmath.nexttoward((half4)(-1747f), (half4)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)0f), maxmath.nexttoward((half4)(-1747f), (half4)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)(-1748f)), maxmath.nexttoward((half4)(-1747f), (half4)(-1748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)(-1746f)), maxmath.nexttoward((half4)(-1747f), (half4)(-1746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)float.NegativeInfinity), maxmath.nexttoward((half4)(-1747f), (half4)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)float.PositiveInfinity), maxmath.nexttoward((half4)1747f, (half4)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)0f), maxmath.nexttoward((half4)1747f, (half4)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)1748f), maxmath.nexttoward((half4)1747f, (half4)1748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)1746f), maxmath.nexttoward((half4)1747f, (half4)1746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half4)1747f, (half4)float.NegativeInfinity), maxmath.nexttoward((half4)1747f, (half4)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)float.PositiveInfinity), maxmath.nexttoward((half4)(-1747f), (half4)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)0f), maxmath.nexttoward((half4)(-1747f), (half4)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)(-1748f)), maxmath.nexttoward((half4)(-1747f), (half4)(-1748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)(-1746f)), maxmath.nexttoward((half4)(-1747f), (half4)(-1746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half4)(-1747f), (half4)float.NegativeInfinity), maxmath.nexttoward((half4)(-1747f), (half4)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + [Test] + public static void _half8() + { + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)float.PositiveInfinity), maxmath.nexttoward((half8)1747f, (half8)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)0f), maxmath.nexttoward((half8)1747f, (half8)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)1748f), maxmath.nexttoward((half8)1747f, (half8)1748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)1746f), maxmath.nexttoward((half8)1747f, (half8)1746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)float.NegativeInfinity), maxmath.nexttoward((half8)1747f, (half8)float.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)float.PositiveInfinity), maxmath.nexttoward((half8)(-1747f), (half8)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)0f), maxmath.nexttoward((half8)(-1747f), (half8)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)(-1748f)), maxmath.nexttoward((half8)(-1747f), (half8)(-1748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)(-1746f)), maxmath.nexttoward((half8)(-1747f), (half8)(-1746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)float.NegativeInfinity), maxmath.nexttoward((half8)(-1747f), (half8)float.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)float.PositiveInfinity), maxmath.nexttoward((half8)1747f, (half8)float.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)0f), maxmath.nexttoward((half8)1747f, (half8)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)1748f), maxmath.nexttoward((half8)1747f, (half8)1748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)1746f), maxmath.nexttoward((half8)1747f, (half8)1746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)float.NegativeInfinity), maxmath.nexttoward((half8)1747f, (half8)float.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)float.PositiveInfinity), maxmath.nexttoward((half8)(-1747f), (half8)float.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)0f), maxmath.nexttoward((half8)(-1747f), (half8)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)(-1748f)), maxmath.nexttoward((half8)(-1747f), (half8)(-1748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)(-1746f)), maxmath.nexttoward((half8)(-1747f), (half8)(-1746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)float.NegativeInfinity), maxmath.nexttoward((half8)(-1747f), (half8)float.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)float.PositiveInfinity), maxmath.nexttoward((half8)1747f, (half8)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)0f), maxmath.nexttoward((half8)1747f, (half8)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)1748f), maxmath.nexttoward((half8)1747f, (half8)1748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)1746f), maxmath.nexttoward((half8)1747f, (half8)1746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)float.NegativeInfinity), maxmath.nexttoward((half8)1747f, (half8)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)float.PositiveInfinity), maxmath.nexttoward((half8)(-1747f), (half8)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)0f), maxmath.nexttoward((half8)(-1747f), (half8)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)(-1748f)), maxmath.nexttoward((half8)(-1747f), (half8)(-1748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)(-1746f)), maxmath.nexttoward((half8)(-1747f), (half8)(-1746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)float.NegativeInfinity), maxmath.nexttoward((half8)(-1747f), (half8)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)float.PositiveInfinity), maxmath.nexttoward((half8)1747f, (half8)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)0f), maxmath.nexttoward((half8)1747f, (half8)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)1748f), maxmath.nexttoward((half8)1747f, (half8)1748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)1746f), maxmath.nexttoward((half8)1747f, (half8)1746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half8)1747f, (half8)float.NegativeInfinity), maxmath.nexttoward((half8)1747f, (half8)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)float.PositiveInfinity), maxmath.nexttoward((half8)(-1747f), (half8)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)0f), maxmath.nexttoward((half8)(-1747f), (half8)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)(-1748f)), maxmath.nexttoward((half8)(-1747f), (half8)(-1748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)(-1746f)), maxmath.nexttoward((half8)(-1747f), (half8)(-1746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((half8)(-1747f), (half8)float.NegativeInfinity), maxmath.nexttoward((half8)(-1747f), (half8)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + + [Test] + public static void _float() + { + Assert.AreEqual(maxmath.nexttoward(1747f, float.PositiveInfinity), maxmath.nexttoward(1747f, float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward(1747f, 0f), maxmath.nexttoward(1747f, 0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward(1747f, 1748f), maxmath.nexttoward(1747f, 1748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward(1747f, 1746f), maxmath.nexttoward(1747f, 1746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward(1747f, float.NegativeInfinity), maxmath.nexttoward(1747f, float.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((-1747f), float.PositiveInfinity), maxmath.nexttoward((-1747f), float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((-1747f), 0f), maxmath.nexttoward((-1747f), 0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((-1747f), (-1748f)), maxmath.nexttoward((-1747f), (-1748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((-1747f), (-1746f)), maxmath.nexttoward((-1747f), (-1746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((-1747f), float.NegativeInfinity), maxmath.nexttoward((-1747f), float.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward(1747f, float.PositiveInfinity), maxmath.nexttoward(1747f, float.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward(1747f, 0f), maxmath.nexttoward(1747f, 0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward(1747f, 1748f), maxmath.nexttoward(1747f, 1748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward(1747f, 1746f), maxmath.nexttoward(1747f, 1746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward(1747f, float.NegativeInfinity), maxmath.nexttoward(1747f, float.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((-1747f), float.PositiveInfinity), maxmath.nexttoward((-1747f), float.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((-1747f), 0f), maxmath.nexttoward((-1747f), 0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((-1747f), (-1748f)), maxmath.nexttoward((-1747f), (-1748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((-1747f), (-1746f)), maxmath.nexttoward((-1747f), (-1746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((-1747f), float.NegativeInfinity), maxmath.nexttoward((-1747f), float.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward(1747f, float.PositiveInfinity), maxmath.nexttoward(1747f, float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward(1747f, 0f), maxmath.nexttoward(1747f, 0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward(1747f, 1748f), maxmath.nexttoward(1747f, 1748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward(1747f, 1746f), maxmath.nexttoward(1747f, 1746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward(1747f, float.NegativeInfinity), maxmath.nexttoward(1747f, float.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((-1747f), float.PositiveInfinity), maxmath.nexttoward((-1747f), float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((-1747f), 0f), maxmath.nexttoward((-1747f), 0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((-1747f), (-1748f)), maxmath.nexttoward((-1747f), (-1748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((-1747f), (-1746f)), maxmath.nexttoward((-1747f), (-1746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((-1747f), float.NegativeInfinity), maxmath.nexttoward((-1747f), float.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward(1747f, float.PositiveInfinity), maxmath.nexttoward(1747f, float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward(1747f, 0f), maxmath.nexttoward(1747f, 0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward(1747f, 1748f), maxmath.nexttoward(1747f, 1748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward(1747f, 1746f), maxmath.nexttoward(1747f, 1746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward(1747f, float.NegativeInfinity), maxmath.nexttoward(1747f, float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((-1747f), float.PositiveInfinity), maxmath.nexttoward((-1747f), float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((-1747f), 0f), maxmath.nexttoward((-1747f), 0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((-1747f), (-1748f)), maxmath.nexttoward((-1747f), (-1748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((-1747f), (-1746f)), maxmath.nexttoward((-1747f), (-1746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((-1747f), float.NegativeInfinity), maxmath.nexttoward((-1747f), float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + [Test] + public static void _float2() + { + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)float.PositiveInfinity), maxmath.nexttoward((float2)1747f, (float2)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)0f), maxmath.nexttoward((float2)1747f, (float2)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)1748f), maxmath.nexttoward((float2)1747f, (float2)1748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)1746f), maxmath.nexttoward((float2)1747f, (float2)1746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)float.NegativeInfinity), maxmath.nexttoward((float2)1747f, (float2)float.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)float.PositiveInfinity), maxmath.nexttoward((float2)(-1747f), (float2)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)0f), maxmath.nexttoward((float2)(-1747f), (float2)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)(-1748f)), maxmath.nexttoward((float2)(-1747f), (float2)(-1748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)(-1746f)), maxmath.nexttoward((float2)(-1747f), (float2)(-1746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)float.NegativeInfinity), maxmath.nexttoward((float2)(-1747f), (float2)float.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)float.PositiveInfinity), maxmath.nexttoward((float2)1747f, (float2)float.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)0f), maxmath.nexttoward((float2)1747f, (float2)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)1748f), maxmath.nexttoward((float2)1747f, (float2)1748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)1746f), maxmath.nexttoward((float2)1747f, (float2)1746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)float.NegativeInfinity), maxmath.nexttoward((float2)1747f, (float2)float.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)float.PositiveInfinity), maxmath.nexttoward((float2)(-1747f), (float2)float.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)0f), maxmath.nexttoward((float2)(-1747f), (float2)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)(-1748f)), maxmath.nexttoward((float2)(-1747f), (float2)(-1748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)(-1746f)), maxmath.nexttoward((float2)(-1747f), (float2)(-1746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)float.NegativeInfinity), maxmath.nexttoward((float2)(-1747f), (float2)float.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)float.PositiveInfinity), maxmath.nexttoward((float2)1747f, (float2)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)0f), maxmath.nexttoward((float2)1747f, (float2)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)1748f), maxmath.nexttoward((float2)1747f, (float2)1748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)1746f), maxmath.nexttoward((float2)1747f, (float2)1746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)float.NegativeInfinity), maxmath.nexttoward((float2)1747f, (float2)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)float.PositiveInfinity), maxmath.nexttoward((float2)(-1747f), (float2)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)0f), maxmath.nexttoward((float2)(-1747f), (float2)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)(-1748f)), maxmath.nexttoward((float2)(-1747f), (float2)(-1748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)(-1746f)), maxmath.nexttoward((float2)(-1747f), (float2)(-1746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)float.NegativeInfinity), maxmath.nexttoward((float2)(-1747f), (float2)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)float.PositiveInfinity), maxmath.nexttoward((float2)1747f, (float2)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)0f), maxmath.nexttoward((float2)1747f, (float2)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)1748f), maxmath.nexttoward((float2)1747f, (float2)1748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)1746f), maxmath.nexttoward((float2)1747f, (float2)1746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float2)1747f, (float2)float.NegativeInfinity), maxmath.nexttoward((float2)1747f, (float2)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)float.PositiveInfinity), maxmath.nexttoward((float2)(-1747f), (float2)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)0f), maxmath.nexttoward((float2)(-1747f), (float2)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)(-1748f)), maxmath.nexttoward((float2)(-1747f), (float2)(-1748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)(-1746f)), maxmath.nexttoward((float2)(-1747f), (float2)(-1746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float2)(-1747f), (float2)float.NegativeInfinity), maxmath.nexttoward((float2)(-1747f), (float2)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + [Test] + public static void _float3() + { + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)float.PositiveInfinity), maxmath.nexttoward((float3)1747f, (float3)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)0f), maxmath.nexttoward((float3)1747f, (float3)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)1748f), maxmath.nexttoward((float3)1747f, (float3)1748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)1746f), maxmath.nexttoward((float3)1747f, (float3)1746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)float.NegativeInfinity), maxmath.nexttoward((float3)1747f, (float3)float.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)float.PositiveInfinity), maxmath.nexttoward((float3)(-1747f), (float3)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)0f), maxmath.nexttoward((float3)(-1747f), (float3)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)(-1748f)), maxmath.nexttoward((float3)(-1747f), (float3)(-1748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)(-1746f)), maxmath.nexttoward((float3)(-1747f), (float3)(-1746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)float.NegativeInfinity), maxmath.nexttoward((float3)(-1747f), (float3)float.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)float.PositiveInfinity), maxmath.nexttoward((float3)1747f, (float3)float.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)0f), maxmath.nexttoward((float3)1747f, (float3)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)1748f), maxmath.nexttoward((float3)1747f, (float3)1748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)1746f), maxmath.nexttoward((float3)1747f, (float3)1746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)float.NegativeInfinity), maxmath.nexttoward((float3)1747f, (float3)float.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)float.PositiveInfinity), maxmath.nexttoward((float3)(-1747f), (float3)float.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)0f), maxmath.nexttoward((float3)(-1747f), (float3)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)(-1748f)), maxmath.nexttoward((float3)(-1747f), (float3)(-1748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)(-1746f)), maxmath.nexttoward((float3)(-1747f), (float3)(-1746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)float.NegativeInfinity), maxmath.nexttoward((float3)(-1747f), (float3)float.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)float.PositiveInfinity), maxmath.nexttoward((float3)1747f, (float3)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)0f), maxmath.nexttoward((float3)1747f, (float3)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)1748f), maxmath.nexttoward((float3)1747f, (float3)1748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)1746f), maxmath.nexttoward((float3)1747f, (float3)1746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)float.NegativeInfinity), maxmath.nexttoward((float3)1747f, (float3)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)float.PositiveInfinity), maxmath.nexttoward((float3)(-1747f), (float3)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)0f), maxmath.nexttoward((float3)(-1747f), (float3)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)(-1748f)), maxmath.nexttoward((float3)(-1747f), (float3)(-1748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)(-1746f)), maxmath.nexttoward((float3)(-1747f), (float3)(-1746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)float.NegativeInfinity), maxmath.nexttoward((float3)(-1747f), (float3)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)float.PositiveInfinity), maxmath.nexttoward((float3)1747f, (float3)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)0f), maxmath.nexttoward((float3)1747f, (float3)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)1748f), maxmath.nexttoward((float3)1747f, (float3)1748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)1746f), maxmath.nexttoward((float3)1747f, (float3)1746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float3)1747f, (float3)float.NegativeInfinity), maxmath.nexttoward((float3)1747f, (float3)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)float.PositiveInfinity), maxmath.nexttoward((float3)(-1747f), (float3)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)0f), maxmath.nexttoward((float3)(-1747f), (float3)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)(-1748f)), maxmath.nexttoward((float3)(-1747f), (float3)(-1748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)(-1746f)), maxmath.nexttoward((float3)(-1747f), (float3)(-1746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float3)(-1747f), (float3)float.NegativeInfinity), maxmath.nexttoward((float3)(-1747f), (float3)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + [Test] + public static void _float4() + { + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)float.PositiveInfinity), maxmath.nexttoward((float4)1747f, (float4)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)0f), maxmath.nexttoward((float4)1747f, (float4)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)1748f), maxmath.nexttoward((float4)1747f, (float4)1748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)1746f), maxmath.nexttoward((float4)1747f, (float4)1746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)float.NegativeInfinity), maxmath.nexttoward((float4)1747f, (float4)float.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)float.PositiveInfinity), maxmath.nexttoward((float4)(-1747f), (float4)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)0f), maxmath.nexttoward((float4)(-1747f), (float4)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)(-1748f)), maxmath.nexttoward((float4)(-1747f), (float4)(-1748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)(-1746f)), maxmath.nexttoward((float4)(-1747f), (float4)(-1746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)float.NegativeInfinity), maxmath.nexttoward((float4)(-1747f), (float4)float.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)float.PositiveInfinity), maxmath.nexttoward((float4)1747f, (float4)float.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)0f), maxmath.nexttoward((float4)1747f, (float4)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)1748f), maxmath.nexttoward((float4)1747f, (float4)1748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)1746f), maxmath.nexttoward((float4)1747f, (float4)1746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)float.NegativeInfinity), maxmath.nexttoward((float4)1747f, (float4)float.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)float.PositiveInfinity), maxmath.nexttoward((float4)(-1747f), (float4)float.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)0f), maxmath.nexttoward((float4)(-1747f), (float4)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)(-1748f)), maxmath.nexttoward((float4)(-1747f), (float4)(-1748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)(-1746f)), maxmath.nexttoward((float4)(-1747f), (float4)(-1746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)float.NegativeInfinity), maxmath.nexttoward((float4)(-1747f), (float4)float.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)float.PositiveInfinity), maxmath.nexttoward((float4)1747f, (float4)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)0f), maxmath.nexttoward((float4)1747f, (float4)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)1748f), maxmath.nexttoward((float4)1747f, (float4)1748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)1746f), maxmath.nexttoward((float4)1747f, (float4)1746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)float.NegativeInfinity), maxmath.nexttoward((float4)1747f, (float4)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)float.PositiveInfinity), maxmath.nexttoward((float4)(-1747f), (float4)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)0f), maxmath.nexttoward((float4)(-1747f), (float4)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)(-1748f)), maxmath.nexttoward((float4)(-1747f), (float4)(-1748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)(-1746f)), maxmath.nexttoward((float4)(-1747f), (float4)(-1746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)float.NegativeInfinity), maxmath.nexttoward((float4)(-1747f), (float4)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)float.PositiveInfinity), maxmath.nexttoward((float4)1747f, (float4)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)0f), maxmath.nexttoward((float4)1747f, (float4)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)1748f), maxmath.nexttoward((float4)1747f, (float4)1748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)1746f), maxmath.nexttoward((float4)1747f, (float4)1746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float4)1747f, (float4)float.NegativeInfinity), maxmath.nexttoward((float4)1747f, (float4)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)float.PositiveInfinity), maxmath.nexttoward((float4)(-1747f), (float4)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)0f), maxmath.nexttoward((float4)(-1747f), (float4)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)(-1748f)), maxmath.nexttoward((float4)(-1747f), (float4)(-1748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)(-1746f)), maxmath.nexttoward((float4)(-1747f), (float4)(-1746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float4)(-1747f), (float4)float.NegativeInfinity), maxmath.nexttoward((float4)(-1747f), (float4)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + [Test] + public static void _float8() + { + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)float.PositiveInfinity), maxmath.nexttoward((float8)1747f, (float8)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)0f), maxmath.nexttoward((float8)1747f, (float8)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)1748f), maxmath.nexttoward((float8)1747f, (float8)1748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)1746f), maxmath.nexttoward((float8)1747f, (float8)1746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)float.NegativeInfinity), maxmath.nexttoward((float8)1747f, (float8)float.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)float.PositiveInfinity), maxmath.nexttoward((float8)(-1747f), (float8)float.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)0f), maxmath.nexttoward((float8)(-1747f), (float8)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)(-1748f)), maxmath.nexttoward((float8)(-1747f), (float8)(-1748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)(-1746f)), maxmath.nexttoward((float8)(-1747f), (float8)(-1746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)float.NegativeInfinity), maxmath.nexttoward((float8)(-1747f), (float8)float.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)float.PositiveInfinity), maxmath.nexttoward((float8)1747f, (float8)float.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)0f), maxmath.nexttoward((float8)1747f, (float8)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)1748f), maxmath.nexttoward((float8)1747f, (float8)1748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)1746f), maxmath.nexttoward((float8)1747f, (float8)1746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)float.NegativeInfinity), maxmath.nexttoward((float8)1747f, (float8)float.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)float.PositiveInfinity), maxmath.nexttoward((float8)(-1747f), (float8)float.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)0f), maxmath.nexttoward((float8)(-1747f), (float8)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)(-1748f)), maxmath.nexttoward((float8)(-1747f), (float8)(-1748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)(-1746f)), maxmath.nexttoward((float8)(-1747f), (float8)(-1746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)float.NegativeInfinity), maxmath.nexttoward((float8)(-1747f), (float8)float.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)float.PositiveInfinity), maxmath.nexttoward((float8)1747f, (float8)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)0f), maxmath.nexttoward((float8)1747f, (float8)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)1748f), maxmath.nexttoward((float8)1747f, (float8)1748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)1746f), maxmath.nexttoward((float8)1747f, (float8)1746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)float.NegativeInfinity), maxmath.nexttoward((float8)1747f, (float8)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)float.PositiveInfinity), maxmath.nexttoward((float8)(-1747f), (float8)float.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)0f), maxmath.nexttoward((float8)(-1747f), (float8)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)(-1748f)), maxmath.nexttoward((float8)(-1747f), (float8)(-1748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)(-1746f)), maxmath.nexttoward((float8)(-1747f), (float8)(-1746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)float.NegativeInfinity), maxmath.nexttoward((float8)(-1747f), (float8)float.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)float.PositiveInfinity), maxmath.nexttoward((float8)1747f, (float8)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)0f), maxmath.nexttoward((float8)1747f, (float8)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)1748f), maxmath.nexttoward((float8)1747f, (float8)1748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)1746f), maxmath.nexttoward((float8)1747f, (float8)1746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float8)1747f, (float8)float.NegativeInfinity), maxmath.nexttoward((float8)1747f, (float8)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)float.PositiveInfinity), maxmath.nexttoward((float8)(-1747f), (float8)float.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)0f), maxmath.nexttoward((float8)(-1747f), (float8)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)(-1748f)), maxmath.nexttoward((float8)(-1747f), (float8)(-1748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)(-1746f)), maxmath.nexttoward((float8)(-1747f), (float8)(-1746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((float8)(-1747f), (float8)float.NegativeInfinity), maxmath.nexttoward((float8)(-1747f), (float8)float.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + + [Test] + public static void _double() + { + Assert.AreEqual(maxmath.nexttoward(1747f, double.PositiveInfinity), maxmath.nexttoward(1747f, double.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward(1747f, 0f), maxmath.nexttoward(1747f, 0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward(1747f, 1748f), maxmath.nexttoward(1747f, 1748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward(1747f, 1746f), maxmath.nexttoward(1747f, 1746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward(1747f, double.NegativeInfinity), maxmath.nexttoward(1747f, double.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((-1747f), double.PositiveInfinity), maxmath.nexttoward((-1747f), double.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((-1747f), 0f), maxmath.nexttoward((-1747f), 0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((-1747f), (-1748f)), maxmath.nexttoward((-1747f), (-1748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((-1747f), (-1746f)), maxmath.nexttoward((-1747f), (-1746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((-1747f), double.NegativeInfinity), maxmath.nexttoward((-1747f), double.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward(1747f, double.PositiveInfinity), maxmath.nexttoward(1747f, double.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward(1747f, 0f), maxmath.nexttoward(1747f, 0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward(1747f, 1748f), maxmath.nexttoward(1747f, 1748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward(1747f, 1746f), maxmath.nexttoward(1747f, 1746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward(1747f, double.NegativeInfinity), maxmath.nexttoward(1747f, double.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((-1747f), double.PositiveInfinity), maxmath.nexttoward((-1747f), double.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((-1747f), 0f), maxmath.nexttoward((-1747f), 0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((-1747f), (-1748f)), maxmath.nexttoward((-1747f), (-1748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((-1747f), (-1746f)), maxmath.nexttoward((-1747f), (-1746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((-1747f), double.NegativeInfinity), maxmath.nexttoward((-1747f), double.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward(1747f, double.PositiveInfinity), maxmath.nexttoward(1747f, double.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward(1747f, 0f), maxmath.nexttoward(1747f, 0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward(1747f, 1748f), maxmath.nexttoward(1747f, 1748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward(1747f, 1746f), maxmath.nexttoward(1747f, 1746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward(1747f, double.NegativeInfinity), maxmath.nexttoward(1747f, double.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((-1747f), double.PositiveInfinity), maxmath.nexttoward((-1747f), double.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((-1747f), 0f), maxmath.nexttoward((-1747f), 0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((-1747f), (-1748f)), maxmath.nexttoward((-1747f), (-1748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((-1747f), (-1746f)), maxmath.nexttoward((-1747f), (-1746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((-1747f), double.NegativeInfinity), maxmath.nexttoward((-1747f), double.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward(1747f, double.PositiveInfinity), maxmath.nexttoward(1747f, double.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward(1747f, 0f), maxmath.nexttoward(1747f, 0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward(1747f, 1748f), maxmath.nexttoward(1747f, 1748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward(1747f, 1746f), maxmath.nexttoward(1747f, 1746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward(1747f, double.NegativeInfinity), maxmath.nexttoward(1747f, double.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((-1747f), double.PositiveInfinity), maxmath.nexttoward((-1747f), double.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((-1747f), 0f), maxmath.nexttoward((-1747f), 0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((-1747f), (-1748f)), maxmath.nexttoward((-1747f), (-1748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((-1747f), (-1746f)), maxmath.nexttoward((-1747f), (-1746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((-1747f), double.NegativeInfinity), maxmath.nexttoward((-1747f), double.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + [Test] + public static void _double2() + { + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)double.PositiveInfinity), maxmath.nexttoward((double2)1747f, (double2)double.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)0f), maxmath.nexttoward((double2)1747f, (double2)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)1748f), maxmath.nexttoward((double2)1747f, (double2)1748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)1746f), maxmath.nexttoward((double2)1747f, (double2)1746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)double.NegativeInfinity), maxmath.nexttoward((double2)1747f, (double2)double.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)double.PositiveInfinity), maxmath.nexttoward((double2)(-1747f), (double2)double.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)0f), maxmath.nexttoward((double2)(-1747f), (double2)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)(-1748f)), maxmath.nexttoward((double2)(-1747f), (double2)(-1748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)(-1746f)), maxmath.nexttoward((double2)(-1747f), (double2)(-1746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)double.NegativeInfinity), maxmath.nexttoward((double2)(-1747f), (double2)double.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)double.PositiveInfinity), maxmath.nexttoward((double2)1747f, (double2)double.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)0f), maxmath.nexttoward((double2)1747f, (double2)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)1748f), maxmath.nexttoward((double2)1747f, (double2)1748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)1746f), maxmath.nexttoward((double2)1747f, (double2)1746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)double.NegativeInfinity), maxmath.nexttoward((double2)1747f, (double2)double.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)double.PositiveInfinity), maxmath.nexttoward((double2)(-1747f), (double2)double.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)0f), maxmath.nexttoward((double2)(-1747f), (double2)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)(-1748f)), maxmath.nexttoward((double2)(-1747f), (double2)(-1748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)(-1746f)), maxmath.nexttoward((double2)(-1747f), (double2)(-1746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)double.NegativeInfinity), maxmath.nexttoward((double2)(-1747f), (double2)double.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)double.PositiveInfinity), maxmath.nexttoward((double2)1747f, (double2)double.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)0f), maxmath.nexttoward((double2)1747f, (double2)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)1748f), maxmath.nexttoward((double2)1747f, (double2)1748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)1746f), maxmath.nexttoward((double2)1747f, (double2)1746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)double.NegativeInfinity), maxmath.nexttoward((double2)1747f, (double2)double.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)double.PositiveInfinity), maxmath.nexttoward((double2)(-1747f), (double2)double.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)0f), maxmath.nexttoward((double2)(-1747f), (double2)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)(-1748f)), maxmath.nexttoward((double2)(-1747f), (double2)(-1748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)(-1746f)), maxmath.nexttoward((double2)(-1747f), (double2)(-1746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)double.NegativeInfinity), maxmath.nexttoward((double2)(-1747f), (double2)double.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)double.PositiveInfinity), maxmath.nexttoward((double2)1747f, (double2)double.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)0f), maxmath.nexttoward((double2)1747f, (double2)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)1748f), maxmath.nexttoward((double2)1747f, (double2)1748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)1746f), maxmath.nexttoward((double2)1747f, (double2)1746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double2)1747f, (double2)double.NegativeInfinity), maxmath.nexttoward((double2)1747f, (double2)double.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)double.PositiveInfinity), maxmath.nexttoward((double2)(-1747f), (double2)double.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)0f), maxmath.nexttoward((double2)(-1747f), (double2)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)(-1748f)), maxmath.nexttoward((double2)(-1747f), (double2)(-1748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)(-1746f)), maxmath.nexttoward((double2)(-1747f), (double2)(-1746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double2)(-1747f), (double2)double.NegativeInfinity), maxmath.nexttoward((double2)(-1747f), (double2)double.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + [Test] + public static void _double3() + { + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)double.PositiveInfinity), maxmath.nexttoward((double3)1747f, (double3)double.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)0f), maxmath.nexttoward((double3)1747f, (double3)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)1748f), maxmath.nexttoward((double3)1747f, (double3)1748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)1746f), maxmath.nexttoward((double3)1747f, (double3)1746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)double.NegativeInfinity), maxmath.nexttoward((double3)1747f, (double3)double.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)double.PositiveInfinity), maxmath.nexttoward((double3)(-1747f), (double3)double.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)0f), maxmath.nexttoward((double3)(-1747f), (double3)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)(-1748f)), maxmath.nexttoward((double3)(-1747f), (double3)(-1748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)(-1746f)), maxmath.nexttoward((double3)(-1747f), (double3)(-1746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)double.NegativeInfinity), maxmath.nexttoward((double3)(-1747f), (double3)double.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)double.PositiveInfinity), maxmath.nexttoward((double3)1747f, (double3)double.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)0f), maxmath.nexttoward((double3)1747f, (double3)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)1748f), maxmath.nexttoward((double3)1747f, (double3)1748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)1746f), maxmath.nexttoward((double3)1747f, (double3)1746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)double.NegativeInfinity), maxmath.nexttoward((double3)1747f, (double3)double.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)double.PositiveInfinity), maxmath.nexttoward((double3)(-1747f), (double3)double.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)0f), maxmath.nexttoward((double3)(-1747f), (double3)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)(-1748f)), maxmath.nexttoward((double3)(-1747f), (double3)(-1748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)(-1746f)), maxmath.nexttoward((double3)(-1747f), (double3)(-1746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)double.NegativeInfinity), maxmath.nexttoward((double3)(-1747f), (double3)double.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)double.PositiveInfinity), maxmath.nexttoward((double3)1747f, (double3)double.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)0f), maxmath.nexttoward((double3)1747f, (double3)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)1748f), maxmath.nexttoward((double3)1747f, (double3)1748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)1746f), maxmath.nexttoward((double3)1747f, (double3)1746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)double.NegativeInfinity), maxmath.nexttoward((double3)1747f, (double3)double.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)double.PositiveInfinity), maxmath.nexttoward((double3)(-1747f), (double3)double.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)0f), maxmath.nexttoward((double3)(-1747f), (double3)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)(-1748f)), maxmath.nexttoward((double3)(-1747f), (double3)(-1748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)(-1746f)), maxmath.nexttoward((double3)(-1747f), (double3)(-1746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)double.NegativeInfinity), maxmath.nexttoward((double3)(-1747f), (double3)double.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)double.PositiveInfinity), maxmath.nexttoward((double3)1747f, (double3)double.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)0f), maxmath.nexttoward((double3)1747f, (double3)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)1748f), maxmath.nexttoward((double3)1747f, (double3)1748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)1746f), maxmath.nexttoward((double3)1747f, (double3)1746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double3)1747f, (double3)double.NegativeInfinity), maxmath.nexttoward((double3)1747f, (double3)double.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)double.PositiveInfinity), maxmath.nexttoward((double3)(-1747f), (double3)double.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)0f), maxmath.nexttoward((double3)(-1747f), (double3)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)(-1748f)), maxmath.nexttoward((double3)(-1747f), (double3)(-1748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)(-1746f)), maxmath.nexttoward((double3)(-1747f), (double3)(-1746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double3)(-1747f), (double3)double.NegativeInfinity), maxmath.nexttoward((double3)(-1747f), (double3)double.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + + [Test] + public static void _double4() + { + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)double.PositiveInfinity), maxmath.nexttoward((double4)1747f, (double4)double.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)0f), maxmath.nexttoward((double4)1747f, (double4)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)1748f), maxmath.nexttoward((double4)1747f, (double4)1748f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)1746f), maxmath.nexttoward((double4)1747f, (double4)1746f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)double.NegativeInfinity), maxmath.nexttoward((double4)1747f, (double4)double.NegativeInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)double.PositiveInfinity), maxmath.nexttoward((double4)(-1747f), (double4)double.PositiveInfinity, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)0f), maxmath.nexttoward((double4)(-1747f), (double4)0f, maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)(-1748f)), maxmath.nexttoward((double4)(-1747f), (double4)(-1748f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)(-1746f)), maxmath.nexttoward((double4)(-1747f), (double4)(-1746f), maxmath.Promise.NonZero)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)double.NegativeInfinity), maxmath.nexttoward((double4)(-1747f), (double4)double.NegativeInfinity, maxmath.Promise.NonZero)); + + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)double.PositiveInfinity), maxmath.nexttoward((double4)1747f, (double4)double.PositiveInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)0f), maxmath.nexttoward((double4)1747f, (double4)0f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)1748f), maxmath.nexttoward((double4)1747f, (double4)1748f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)1746f), maxmath.nexttoward((double4)1747f, (double4)1746f, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)double.NegativeInfinity), maxmath.nexttoward((double4)1747f, (double4)double.NegativeInfinity, maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)double.PositiveInfinity), maxmath.nexttoward((double4)(-1747f), (double4)double.PositiveInfinity, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)0f), maxmath.nexttoward((double4)(-1747f), (double4)0f, maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)(-1748f)), maxmath.nexttoward((double4)(-1747f), (double4)(-1748f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)(-1746f)), maxmath.nexttoward((double4)(-1747f), (double4)(-1746f), maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)double.NegativeInfinity), maxmath.nexttoward((double4)(-1747f), (double4)double.NegativeInfinity, maxmath.Promise.Negative)); + + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)double.PositiveInfinity), maxmath.nexttoward((double4)1747f, (double4)double.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)0f), maxmath.nexttoward((double4)1747f, (double4)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)1748f), maxmath.nexttoward((double4)1747f, (double4)1748f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)1746f), maxmath.nexttoward((double4)1747f, (double4)1746f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)double.NegativeInfinity), maxmath.nexttoward((double4)1747f, (double4)double.NegativeInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)double.PositiveInfinity), maxmath.nexttoward((double4)(-1747f), (double4)double.PositiveInfinity, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)0f), maxmath.nexttoward((double4)(-1747f), (double4)0f, maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)(-1748f)), maxmath.nexttoward((double4)(-1747f), (double4)(-1748f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)(-1746f)), maxmath.nexttoward((double4)(-1747f), (double4)(-1746f), maxmath.Promise.Unsafe0)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)double.NegativeInfinity), maxmath.nexttoward((double4)(-1747f), (double4)double.NegativeInfinity, maxmath.Promise.Unsafe0)); + + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)double.PositiveInfinity), maxmath.nexttoward((double4)1747f, (double4)double.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)0f), maxmath.nexttoward((double4)1747f, (double4)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)1748f), maxmath.nexttoward((double4)1747f, (double4)1748f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)1746f), maxmath.nexttoward((double4)1747f, (double4)1746f, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double4)1747f, (double4)double.NegativeInfinity), maxmath.nexttoward((double4)1747f, (double4)double.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Positive)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)double.PositiveInfinity), maxmath.nexttoward((double4)(-1747f), (double4)double.PositiveInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)0f), maxmath.nexttoward((double4)(-1747f), (double4)0f, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)(-1748f)), maxmath.nexttoward((double4)(-1747f), (double4)(-1748f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)(-1746f)), maxmath.nexttoward((double4)(-1747f), (double4)(-1746f), maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + Assert.AreEqual(maxmath.nexttoward((double4)(-1747f), (double4)double.NegativeInfinity), maxmath.nexttoward((double4)(-1747f), (double4)double.NegativeInfinity, maxmath.Promise.Unsafe0 | maxmath.Promise.Negative)); + } + } +} diff --git a/Tests/Editor/Functions/Promises/nexttoward.cs.meta b/Tests/Editor/Functions/Promises/nexttoward.cs.meta new file mode 100644 index 0000000..b66cc3a --- /dev/null +++ b/Tests/Editor/Functions/Promises/nexttoward.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd8a16f60b5b48b4fbace6455da5b9dc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Editor/Functions/Promises/perm.cs b/Tests/Editor/Functions/Promises/perm.cs new file mode 100644 index 0000000..10533be --- /dev/null +++ b/Tests/Editor/Functions/Promises/perm.cs @@ -0,0 +1,481 @@ +using NUnit.Framework; +using Unity.Mathematics; + +using static MaxMath.LUT.FACTORIAL; + +namespace MaxMath.Tests +{ + public static class PROMISE_perm + { + [Test] + public static void _byte2() + { + Random8 rng = Random8.New; + byte2 n; + byte2 k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextByte2(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextByte2(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextByte2(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextByte2(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + + n = rng.NextByte2(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextByte2(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe2)); + + n = rng.NextByte2(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextByte2(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe3)); + } + } + + [Test] + public static void _byte3() + { + Random8 rng = Random8.New; + byte3 n; + byte3 k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextByte3(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextByte3(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextByte3(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextByte3(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + + n = rng.NextByte3(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextByte3(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe2)); + + n = rng.NextByte3(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextByte3(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe3)); + } + } + + [Test] + public static void _byte4() + { + Random8 rng = Random8.New; + byte4 n; + byte4 k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextByte4(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextByte4(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextByte4(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextByte4(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + + n = rng.NextByte4(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextByte4(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe2)); + + n = rng.NextByte4(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextByte4(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe3)); + } + } + + [Test] + public static void _byte8() + { + Random8 rng = Random8.New; + byte8 n; + byte8 k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextByte8(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextByte8(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextByte8(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextByte8(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + + n = rng.NextByte8(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextByte8(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe2)); + + n = rng.NextByte8(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextByte8(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe3)); + } + } + + [Test] + public static void _byte16() + { + Random8 rng = Random8.New; + byte16 n; + byte16 k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextByte16(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextByte16(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextByte16(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextByte16(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + + n = rng.NextByte16(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextByte16(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe2)); + + n = rng.NextByte16(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextByte16(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe3)); + } + } + + [Test] + public static void _byte32() + { + Random8 rng = Random8.New; + byte32 n; + byte32 k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextByte32(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextByte32(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextByte32(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextByte32(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + + n = rng.NextByte32(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextByte32(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe2)); + + n = rng.NextByte32(0, MAX_INVERSE_FACTORIAL_U8 + 1); + k = rng.NextByte32(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe3)); + } + } + + + [Test] + public static void _ushort2() + { + Random16 rng = Random16.New; + ushort2 n; + ushort2 k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUShort2(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUShort2(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextUShort2(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUShort2(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + + n = rng.NextUShort2(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextUShort2(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe2)); + } + } + + [Test] + public static void _ushort3() + { + Random16 rng = Random16.New; + ushort3 n; + ushort3 k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUShort3(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUShort3(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextUShort3(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUShort3(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + + n = rng.NextUShort3(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextUShort3(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe2)); + } + } + + [Test] + public static void _ushort4() + { + Random16 rng = Random16.New; + ushort4 n; + ushort4 k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUShort4(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUShort4(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextUShort4(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUShort4(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + + n = rng.NextUShort4(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextUShort4(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe2)); + } + } + + [Test] + public static void _ushort8() + { + Random16 rng = Random16.New; + ushort8 n; + ushort8 k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUShort8(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUShort8(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextUShort8(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUShort8(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + + n = rng.NextUShort8(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextUShort8(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe2)); + } + } + + [Test] + public static void _ushort16() + { + Random16 rng = Random16.New; + ushort16 n; + ushort16 k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUShort16(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUShort16(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextUShort16(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUShort16(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + + n = rng.NextUShort16(0, MAX_INVERSE_FACTORIAL_U16 + 1); + k = rng.NextUShort16(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe2)); + } + } + + + [Test] + public static void _uint() + { + Random32 rng = Random32.New; + uint n; + uint k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUInt(0, MAX_INVERSE_FACTORIAL_U128 + 1); + k = rng.NextUInt(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextUInt(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUInt(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + } + } + + [Test] + public static void _uint2() + { + Random32 rng = Random32.New; + uint2 n; + uint2 k; + + for (uint i = 0; i < 24; i++) + { + n = rng.NextUInt2(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUInt2(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextUInt2(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUInt2(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + } + } + + [Test] + public static void _uint3() + { + Random32 rng = Random32.New; + uint3 n; + uint3 k; + + for (uint i = 0; i < 24; i++) + { + n = rng.NextUInt3(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUInt3(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextUInt3(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUInt3(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + } + } + + [Test] + public static void _uint4() + { + Random32 rng = Random32.New; + uint4 n; + uint4 k; + + for (uint i = 0; i < 24; i++) + { + n = rng.NextUInt4(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUInt4(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextUInt4(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUInt4(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + } + } + + [Test] + public static void _uint8() + { + Random32 rng = Random32.New; + uint8 n; + uint8 k; + + for (uint i = 0; i < 24; i++) + { + n = rng.NextUInt8(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUInt8(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextUInt8(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextUInt8(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + } + } + + + [Test] + public static void _ulong() + { + Random64 rng = Random64.New; + ulong n; + ulong k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextULong(0, MAX_INVERSE_FACTORIAL_U128 + 1); + k = rng.NextULong(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextULong(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextULong(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + } + } + + [Test] + public static void _ulong2() + { + Random64 rng = Random64.New; + ulong2 n; + ulong2 k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextULong2(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextULong2(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextULong2(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextULong2(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + } + } + + [Test] + public static void _ulong3() + { + Random64 rng = Random64.New; + ulong3 n; + ulong3 k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextULong3(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextULong3(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextULong3(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextULong3(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + } + } + + [Test] + public static void _ulong4() + { + Random64 rng = Random64.New; + ulong4 n; + ulong4 k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextULong4(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextULong4(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextULong4(0, MAX_INVERSE_FACTORIAL_U32 + 1); + k = rng.NextULong4(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + } + } + + + [Test] + public static void _uint128() + { + Random128 rng = Random128.New; + UInt128 n; + UInt128 k; + + for (int i = 0; i < 24; i++) + { + n = rng.NextUInt128(0, MAX_INVERSE_FACTORIAL_U128 + 1); + k = rng.NextUInt128(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe0)); + + n = rng.NextUInt128(0, MAX_INVERSE_FACTORIAL_U64 + 1); + k = rng.NextUInt128(0, n + 1); + Assert.AreEqual(maxmath.perm(n, k), maxmath.perm(n, k, maxmath.Promise.Unsafe1)); + } + } + } +} diff --git a/Tests/Editor/Functions/Promises/perm.cs.meta b/Tests/Editor/Functions/Promises/perm.cs.meta new file mode 100644 index 0000000..59a9df9 --- /dev/null +++ b/Tests/Editor/Functions/Promises/perm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ccfcb746d14bdfe4d88daef5e75545e2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Editor/Functions/Promises/rol ror.cs b/Tests/Editor/Functions/Promises/rol ror.cs index 3c9d3b0..589c5cf 100644 --- a/Tests/Editor/Functions/Promises/rol ror.cs +++ b/Tests/Editor/Functions/Promises/rol ror.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/toquarterunsafe.cs b/Tests/Editor/Functions/Promises/toquarterunsafe.cs index 7b281d2..f7e4d4b 100644 --- a/Tests/Editor/Functions/Promises/toquarterunsafe.cs +++ b/Tests/Editor/Functions/Promises/toquarterunsafe.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Functions/Promises/unsafedoublelong.cs b/Tests/Editor/Functions/Promises/unsafedoublelong.cs index 2ad4520..f83daab 100644 --- a/Tests/Editor/Functions/Promises/unsafedoublelong.cs +++ b/Tests/Editor/Functions/Promises/unsafedoublelong.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Unity.Mathematics; namespace MaxMath.Tests diff --git a/Tests/Editor/Testing Tools.cs b/Tests/Editor/Testing Tools.cs deleted file mode 100644 index 8c9e13e..0000000 --- a/Tests/Editor/Testing Tools.cs +++ /dev/null @@ -1,292 +0,0 @@ -using System.IO; -using UnityEngine; -using UnityEditor; -using NUnit.Framework; -using DevTools; - -namespace MaxMath.Tests -{ - public static class ___TESTING___ - { - private static string ProjectPath => Application.dataPath.Substring(0, Application.dataPath.Length - "Assets".AsDirectory().Length).AsDirectory() + "LocalPackages".AsDirectory() + "MaxMath".AsDirectory() + "Runtime"; - - private const string SSE = "Sse.IsSseSupported"; - private const string SSE2 = "Sse2.IsSse2Supported"; - private const string SSE3 = "Sse3.IsSse3Supported"; - private const string SSSE3 = "Ssse3.IsSsse3Supported"; - private const string SSE4_1 = "Sse4_1.IsSse41Supported"; - private const string SSE4_2 = "Sse4_2.IsSse42Supported"; - private const string AVX = "Avx.IsAvxSupported"; - private const string AVX2 = "Avx2.IsAvx2Supported"; - private const string FMA = "Fma.IsFmaSupported"; - private const string BMI1 = "Bmi1.IsBmi1Supported"; - private const string BMI2 = "Bmi2.IsBmi2Supported"; - private const string POPCNT = "Popcnt.IsPopcntSupported"; - private const string F16C = "F16C.IsF16CSupported"; - - private const string CONST = "Constant.IsConstantExpression"; - - private const string TESTING = "#define TESTING"; - - - private static void DeactivateAll() - { - DeactivateFeatureSet(SSE); - DeactivateFeatureSet(SSE2); - DeactivateFeatureSet(SSE3); - DeactivateFeatureSet(SSSE3); - DeactivateFeatureSet(SSE4_1); - DeactivateFeatureSet(SSE4_2); - DeactivateFeatureSet(AVX); - DeactivateFeatureSet(AVX2); - DeactivateFeatureSet(FMA); - DeactivateFeatureSet(BMI1); - DeactivateFeatureSet(BMI2); - DeactivateFeatureSet(POPCNT); - DeactivateFeatureSet(F16C); - } - - private static void DeactivatePreprocessorDirective(string define) - { - DirectoryExtensions.ForEachFile(ProjectPath, - (file) => - { - if (Path.GetExtension(file) != ".cs") - { - return; - } - - string fileContent = File.ReadAllText(file); - int idx = fileContent.IndexOf(define); - - if (idx > 1 && fileContent[idx - 1] != '/' && fileContent[idx - 2] != '/') - { - fileContent = fileContent.Replace(define, "//" + define); - File.WriteAllText(file, fileContent); - } - }); - } - private static void ActivatePreprocessorDirective(string define) - { - DirectoryExtensions.ForEachFile(ProjectPath, - (file) => - { - if (Path.GetExtension(file) != ".cs") - { - return; - } - - string fileContent = File.ReadAllText(file); - - if (fileContent.Contains("//" + define)) - { - fileContent = fileContent.Replace("//" + define, define); - File.WriteAllText(file, fileContent); - } - }); - } - - private static void DeactivateFeatureSet(string featureSet) - { - DirectoryExtensions.ForEachFile(ProjectPath, - (file) => - { - if (Path.GetExtension(file) != ".cs") - { - return; - } - - string fileContent = File.ReadAllText(file); - - bool any = false; - int index = 0; - while ((index = fileContent.IndexOf("!" + featureSet, index + 1)) != -1) - { - any = true; - fileContent = fileContent.Remove(index, 1); - } - - if (any) - { - File.WriteAllText(file, fileContent); - } - }); - } - private static void ActivateFeatureSet(string featureSet) - { - DirectoryExtensions.ForEachFile(ProjectPath, - (file) => - { - if (Path.GetExtension(file) != ".cs") - { - return; - } - - string fileContent = File.ReadAllText(file); - - bool any = false; - int index = 0; - while ((index = fileContent.IndexOf(featureSet, index + 1)) != -1) - { - any = true; - if (fileContent[index - 1] != '!') - { - fileContent = fileContent.Insert(index, "!"); - index++; - } - } - - if (any) - { - File.WriteAllText(file, fileContent); - } - }); - } - - - [Test] - public static void _00_ACTIVATE_TEST_MODE() - { - DeactivatePreprocessorDirective(TESTING); - - ActivatePreprocessorDirective(TESTING); - - AssetDatabase.Refresh(); - } - - [Test] - public static void _01_ACTIVATE_SSE() - { - DeactivateAll(); - - ActivateFeatureSet(SSE); - - AssetDatabase.Refresh(); - } - - [Test] - public static void _02_ACTIVATE_SSE2() - { - DeactivateAll(); - - ActivateFeatureSet(SSE); - ActivateFeatureSet(SSE2); - - AssetDatabase.Refresh(); - } - - [Test] - public static void _03_ACTIVATE_SSE3() - { - DeactivateAll(); - - ActivateFeatureSet(SSE); - ActivateFeatureSet(SSE2); - ActivateFeatureSet(SSE3); - - AssetDatabase.Refresh(); - } - - [Test] - public static void _04_ACTIVATE_SSSE3() - { - DeactivateAll(); - - ActivateFeatureSet(SSE); - ActivateFeatureSet(SSE2); - ActivateFeatureSet(SSE3); - ActivateFeatureSet(SSSE3); - - AssetDatabase.Refresh(); - } - - [Test] - public static void _05_ACTIVATE_SSE4_1() - { - DeactivateAll(); - - ActivateFeatureSet(SSE); - ActivateFeatureSet(SSE2); - ActivateFeatureSet(SSE3); - ActivateFeatureSet(SSSE3); - ActivateFeatureSet(SSE4_1); - - AssetDatabase.Refresh(); - } - - [Test] - public static void _06_ACTIVATE_SSE4_2() - { - DeactivateAll(); - - ActivateFeatureSet(SSE); - ActivateFeatureSet(SSE2); - ActivateFeatureSet(SSE3); - ActivateFeatureSet(SSSE3); - ActivateFeatureSet(SSE4_1); - ActivateFeatureSet(SSE4_2); - - AssetDatabase.Refresh(); - } - - [Test] - public static void _07_ACTIVATE_AVX() - { - DeactivateAll(); - - ActivateFeatureSet(SSE); - ActivateFeatureSet(SSE2); - ActivateFeatureSet(SSE3); - ActivateFeatureSet(SSSE3); - ActivateFeatureSet(SSE4_1); - ActivateFeatureSet(SSE4_2); - ActivateFeatureSet(AVX); - - AssetDatabase.Refresh(); - } - - [Test] - public static void _08_ACTIVATE_AVX2() - { - DeactivateAll(); - - ActivateFeatureSet(SSE); - ActivateFeatureSet(SSE2); - ActivateFeatureSet(SSE3); - ActivateFeatureSet(SSSE3); - ActivateFeatureSet(SSE4_1); - ActivateFeatureSet(SSE4_2); - ActivateFeatureSet(AVX); - ActivateFeatureSet(AVX2); - ActivateFeatureSet(FMA); - ActivateFeatureSet(BMI1); - ActivateFeatureSet(BMI2); - ActivateFeatureSet(POPCNT); - ActivateFeatureSet(F16C); - - AssetDatabase.Refresh(); - } - - [Test] - public static void _09_ACTIVATE_CONST() - { - DeactivateFeatureSet(CONST); - - ActivateFeatureSet(CONST); - - AssetDatabase.Refresh(); - } - - [Test] - public static void _10_RELEASE_MODE() - { - DeactivatePreprocessorDirective(TESTING); - - DeactivateAll(); - - DeactivateFeatureSet(CONST); - - AssetDatabase.Refresh(); - } - } -} diff --git a/Tests/Editor/Types/test_Int128.cs b/Tests/Editor/Types/test_Int128.cs index d6efb7d..85ee41d 100644 --- a/Tests/Editor/Types/test_Int128.cs +++ b/Tests/Editor/Types/test_Int128.cs @@ -1140,5 +1140,37 @@ public static void ShiftRight() } } } + + + [Test] + new public static void ToString() + { + Random128 rng = Random128.New; + Int128 x = 0; + + Assert.AreEqual(Int128.MAX_DECIMAL_DIGITS, ((BigInteger)Int128.MaxValue).ToString().Length); + Assert.AreEqual(Int128.MAX_DECIMAL_DIGITS + 1, ((BigInteger)Int128.MinValue).ToString().Length); + Assert.AreEqual(x.ToString(), "0"); + Assert.AreEqual(Int128.MinValue.ToString(), ((BigInteger)Int128.MinValue).ToString()); + Assert.AreEqual(Int128.MaxValue.ToString(), ((BigInteger)Int128.MaxValue).ToString()); + + for (int i = 0; i < 25; i++) + { + x = rng.NextInt128(); + Assert.AreEqual(x.ToString(), ((BigInteger)x).ToString()); + x = -x; + Assert.AreEqual(x.ToString(), ((BigInteger)x).ToString()); + + x = rng.NextInt128(0, uint.MaxValue); + Assert.AreEqual(x.ToString(), ((BigInteger)x).ToString()); + x = -x; + Assert.AreEqual(x.ToString(), ((BigInteger)x).ToString()); + + x = rng.NextInt128(0, 10); + Assert.AreEqual(x.ToString(), ((BigInteger)x).ToString()); + x = -x; + Assert.AreEqual(x.ToString(), ((BigInteger)x).ToString()); + } + } } } \ No newline at end of file diff --git a/Tests/Editor/Types/test_byte16.cs b/Tests/Editor/Types/test_byte16.cs index 0b04e16..b62b635 100644 --- a/Tests/Editor/Types/test_byte16.cs +++ b/Tests/Editor/Types/test_byte16.cs @@ -438,21 +438,39 @@ public static void Constructor___byte8_Byte8() public static void Indexer() { Assert.AreEqual(TestData_LHS[0][0] == TestData_LHS[0].x0 & - TestData_LHS[0][1] == TestData_LHS[0].x1 & - TestData_LHS[0][2] == TestData_LHS[0].x2 & - TestData_LHS[0][3] == TestData_LHS[0].x3 & - TestData_LHS[0][4] == TestData_LHS[0].x4 & - TestData_LHS[0][5] == TestData_LHS[0].x5 & - TestData_LHS[0][6] == TestData_LHS[0].x6 & - TestData_LHS[0][7] == TestData_LHS[0].x7 & - TestData_LHS[0][8] == TestData_LHS[0].x8 & - TestData_LHS[0][9] == TestData_LHS[0].x9 & - TestData_LHS[0][10] == TestData_LHS[0].x10 & - TestData_LHS[0][11] == TestData_LHS[0].x11 & - TestData_LHS[0][12] == TestData_LHS[0].x12 & - TestData_LHS[0][13] == TestData_LHS[0].x13 & - TestData_LHS[0][14] == TestData_LHS[0].x14 & - TestData_LHS[0][15] == TestData_LHS[0].x15, true); + TestData_LHS[0][1] == TestData_LHS[0].x1 & + TestData_LHS[0][2] == TestData_LHS[0].x2 & + TestData_LHS[0][3] == TestData_LHS[0].x3 & + TestData_LHS[0][4] == TestData_LHS[0].x4 & + TestData_LHS[0][5] == TestData_LHS[0].x5 & + TestData_LHS[0][6] == TestData_LHS[0].x6 & + TestData_LHS[0][7] == TestData_LHS[0].x7 & + TestData_LHS[0][8] == TestData_LHS[0].x8 & + TestData_LHS[0][9] == TestData_LHS[0].x9 & + TestData_LHS[0][10] == TestData_LHS[0].x10 & + TestData_LHS[0][11] == TestData_LHS[0].x11 & + TestData_LHS[0][12] == TestData_LHS[0].x12 & + TestData_LHS[0][13] == TestData_LHS[0].x13 & + TestData_LHS[0][14] == TestData_LHS[0].x14 & + TestData_LHS[0][15] == TestData_LHS[0].x15, true); + + for (int i = 0; i < 16; i++) + { + byte16 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 16; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_byte2.cs b/Tests/Editor/Types/test_byte2.cs index d036106..a5191cd 100644 --- a/Tests/Editor/Types/test_byte2.cs +++ b/Tests/Editor/Types/test_byte2.cs @@ -62,6 +62,24 @@ public static void Indexer() { Assert.AreEqual(TestData_LHS[0][0] == TestData_LHS[0].x & TestData_LHS[0][1] == TestData_LHS[0].y, true); + + for (int i = 0; i < 2; i++) + { + byte2 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 2; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_byte3.cs b/Tests/Editor/Types/test_byte3.cs index 05c6781..6bda20a 100644 --- a/Tests/Editor/Types/test_byte3.cs +++ b/Tests/Editor/Types/test_byte3.cs @@ -92,6 +92,24 @@ public static void Indexer() Assert.AreEqual(TestData_LHS[0][0] == TestData_LHS[0].x & TestData_LHS[0][1] == TestData_LHS[0].y & TestData_LHS[0][2] == TestData_LHS[0].z, true); + + for (int i = 0; i < 3; i++) + { + byte3 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 3; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_byte32.cs b/Tests/Editor/Types/test_byte32.cs index 03b93bc..2dc824c 100644 --- a/Tests/Editor/Types/test_byte32.cs +++ b/Tests/Editor/Types/test_byte32.cs @@ -1,5 +1,4 @@ using NUnit.Framework; -using Unity.Mathematics; using Unity.Burst.Intrinsics; namespace MaxMath.Tests @@ -39,7 +38,7 @@ unsafe public static class __byte32 x25 = 3, x26 = 32, x27 = 21, - x28 = 0, + x28 = 13, x29 = 47, x30 = 32, x31 = 64}, @@ -558,6 +557,24 @@ public static void Indexer() TestData_LHS[0][29] == TestData_LHS[0].x29 & TestData_LHS[0][30] == TestData_LHS[0].x30 & TestData_LHS[0][31] == TestData_LHS[0].x31, true); + + for (int i = 0; i < 32; i++) + { + byte32 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 32; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_byte4.cs b/Tests/Editor/Types/test_byte4.cs index a423cf5..9ec72cd 100644 --- a/Tests/Editor/Types/test_byte4.cs +++ b/Tests/Editor/Types/test_byte4.cs @@ -149,6 +149,24 @@ public static void Indexer() TestData_LHS[0][1] == TestData_LHS[0].y & TestData_LHS[0][2] == TestData_LHS[0].z & TestData_LHS[0][3] == TestData_LHS[0].w, true); + + for (int i = 0; i < 4; i++) + { + byte4 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 4; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_byte8.cs b/Tests/Editor/Types/test_byte8.cs index 3763241..a8f937b 100644 --- a/Tests/Editor/Types/test_byte8.cs +++ b/Tests/Editor/Types/test_byte8.cs @@ -243,6 +243,24 @@ public static void Indexer() TestData_LHS[0][5] == TestData_LHS[0].x5 & TestData_LHS[0][6] == TestData_LHS[0].x6 & TestData_LHS[0][7] == TestData_LHS[0].x7, true); + + for (int i = 0; i < 8; i++) + { + byte8 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 8; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_float8.cs b/Tests/Editor/Types/test_float8.cs index 5ed227c..78a1ccb 100644 --- a/Tests/Editor/Types/test_float8.cs +++ b/Tests/Editor/Types/test_float8.cs @@ -243,6 +243,24 @@ public static void Indexer() TestData_LHS[0][5] == TestData_LHS[0].x5 & TestData_LHS[0][6] == TestData_LHS[0].x6 & TestData_LHS[0][7] == TestData_LHS[0].x7, true); + + for (int i = 0; i < 8; i++) + { + float8 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 8; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_int8.cs b/Tests/Editor/Types/test_int8.cs index f2af71a..a81ffe0 100644 --- a/Tests/Editor/Types/test_int8.cs +++ b/Tests/Editor/Types/test_int8.cs @@ -243,6 +243,24 @@ public static void Indexer() TestData_LHS[0][5] == TestData_LHS[0].x5 & TestData_LHS[0][6] == TestData_LHS[0].x6 & TestData_LHS[0][7] == TestData_LHS[0].x7, true); + + for (int i = 0; i < 8; i++) + { + int8 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 8; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_long2.cs b/Tests/Editor/Types/test_long2.cs index ee36311..44d5878 100644 --- a/Tests/Editor/Types/test_long2.cs +++ b/Tests/Editor/Types/test_long2.cs @@ -62,6 +62,24 @@ public static void Indexer() { Assert.AreEqual(TestData_LHS[0][0] == TestData_LHS[0].x & TestData_LHS[0][1] == TestData_LHS[0].y, true); + + for (int i = 0; i < 2; i++) + { + long2 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 2; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_long3.cs b/Tests/Editor/Types/test_long3.cs index b559ad7..df1884c 100644 --- a/Tests/Editor/Types/test_long3.cs +++ b/Tests/Editor/Types/test_long3.cs @@ -92,6 +92,24 @@ public static void Indexer() Assert.AreEqual(TestData_LHS[0][0] == TestData_LHS[0].x & TestData_LHS[0][1] == TestData_LHS[0].y & TestData_LHS[0][2] == TestData_LHS[0].z, true); + + for (int i = 0; i < 3; i++) + { + long3 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 3; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_long4.cs b/Tests/Editor/Types/test_long4.cs index dfea5db..c13c450 100644 --- a/Tests/Editor/Types/test_long4.cs +++ b/Tests/Editor/Types/test_long4.cs @@ -149,6 +149,24 @@ public static void Indexer() TestData_LHS[0][1] == TestData_LHS[0].y & TestData_LHS[0][2] == TestData_LHS[0].z & TestData_LHS[0][3] == TestData_LHS[0].w, true); + + for (int i = 0; i < 4; i++) + { + long4 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 4; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_quarter.cs b/Tests/Editor/Types/test_quarter.cs index a5ee7f3..414cdb9 100644 --- a/Tests/Editor/Types/test_quarter.cs +++ b/Tests/Editor/Types/test_quarter.cs @@ -2,32 +2,10 @@ using System.Collections.Generic; using Unity.Mathematics; +#pragma warning disable CS1718 // comparison to same variable is a test case + namespace MaxMath.Tests { - - - // test from float: closest value - - - - - - - - - - - - - - - - - - - - - unsafe public static class __quarter { private static bool IsZero(quarter value) @@ -91,6 +69,58 @@ public static void NotEquals() Assert.IsTrue((quarter)1f != (quarter)(-1f)); } + + + [Test] + public static void LessThan() + { + Random32 rng = Random32.New; + + Assert.IsFalse((quarter)quarter.NaN < (quarter)0f); + Assert.IsFalse((quarter)0f < (quarter)quarter.NaN); + Assert.IsFalse((quarter)quarter.PositiveInfinity < (quarter)quarter.NaN); + Assert.IsFalse((quarter)quarter.NegativeInfinity < (quarter)quarter.NaN); + + for (int i = 0; i < 25; i++) + { + quarter lhs = (quarter)rng.NextFloat(quarter.MinValue, quarter.MaxValue); + quarter rhs = (quarter)rng.NextFloat(quarter.MinValue, quarter.MaxValue); + + Assert.AreEqual(lhs < rhs, (float)lhs < (float)rhs); + Assert.AreEqual(lhs < lhs, (float)lhs < (float)lhs); + + lhs = (quarter)0f; + + Assert.AreEqual(lhs < rhs, (float)lhs < (float)rhs); + Assert.AreEqual(lhs < lhs, (float)lhs < (float)lhs); + } + } + + [Test] + public static void LessEqual() + { + Random32 rng = Random32.New; + + Assert.IsFalse((quarter)quarter.NaN <= (quarter)0f); + Assert.IsFalse((quarter)0f <= (quarter)quarter.NaN); + Assert.IsFalse((quarter)quarter.PositiveInfinity <= (quarter)quarter.NaN); + Assert.IsFalse((quarter)quarter.NegativeInfinity <= (quarter)quarter.NaN); + + for (int i = 0; i < 25; i++) + { + quarter lhs = (quarter)rng.NextFloat(quarter.MinValue, quarter.MaxValue); + quarter rhs = (quarter)rng.NextFloat(quarter.MinValue, quarter.MaxValue); + + Assert.AreEqual(lhs <= rhs, (float)lhs <= (float)rhs); + Assert.AreEqual(lhs <= lhs, (float)lhs <= (float)lhs); + + lhs = (quarter)0f; + + Assert.AreEqual(lhs < rhs, (float)lhs < (float)rhs); + Assert.AreEqual(lhs < lhs, (float)lhs < (float)lhs); + } + } + [Test] public static void ToHalf() @@ -512,6 +542,56 @@ public static void NotEquals2() Assert.IsTrue(math.all((quarter2)(quarter)1f != (quarter)(-1f))); } + + [Test] + public static void LessThan2() + { + Random32 rng = Random32.New; + + Assert.IsFalse(((quarter2)quarter.NaN < (quarter2)0f).x); + Assert.IsFalse(((quarter2)0f < (quarter2)quarter.NaN).x); + Assert.IsFalse(((quarter2)quarter.PositiveInfinity < (quarter2)quarter.NaN).x); + Assert.IsFalse(((quarter2)quarter.NegativeInfinity < (quarter2)quarter.NaN).x); + + for (int i = 0; i < 25; i++) + { + quarter2 lhs = (quarter2)rng.NextFloat2(quarter.MinValue, quarter.MaxValue); + quarter2 rhs = (quarter2)rng.NextFloat2(quarter.MinValue, quarter.MaxValue); + + Assert.AreEqual(lhs < rhs, (float2)lhs < (float2)rhs); + Assert.AreEqual(lhs < lhs, (float2)lhs < (float2)lhs); + + lhs = (quarter2)0f; + + Assert.AreEqual(lhs < rhs, (float2)lhs < (float2)rhs); + Assert.AreEqual(lhs < lhs, (float2)lhs < (float2)lhs); + } + } + + [Test] + public static void LessEqual2() + { + Random32 rng = Random32.New; + + Assert.IsFalse(((quarter2)quarter.NaN <= (quarter2)0f).x); + Assert.IsFalse(((quarter2)0f <= (quarter2)quarter.NaN).x); + Assert.IsFalse(((quarter2)quarter.PositiveInfinity <= (quarter2)quarter.NaN).x); + Assert.IsFalse(((quarter2)quarter.NegativeInfinity <= (quarter2)quarter.NaN).x); + + for (int i = 0; i < 25; i++) + { + quarter2 lhs = (quarter2)rng.NextFloat2(quarter.MinValue, quarter.MaxValue); + quarter2 rhs = (quarter2)rng.NextFloat2(quarter.MinValue, quarter.MaxValue); + + Assert.AreEqual(lhs <= rhs, (float2)lhs <= (float2)rhs); + Assert.AreEqual(lhs <= lhs, (float2)lhs <= (float2)lhs); + + lhs = (quarter2)0f; + + Assert.AreEqual(lhs < rhs, (float2)lhs < (float2)rhs); + Assert.AreEqual(lhs < lhs, (float2)lhs < (float2)lhs); + } + } [Test] public static void ToHalf2() @@ -872,6 +952,56 @@ public static void NotEquals3() Assert.IsTrue(math.all((quarter3)(quarter)1f != (quarter)(-1f))); } + + [Test] + public static void LessThan3() + { + Random32 rng = Random32.New; + + Assert.IsFalse(((quarter3)quarter.NaN < (quarter3)0f).x); + Assert.IsFalse(((quarter3)0f < (quarter3)quarter.NaN).x); + Assert.IsFalse(((quarter3)quarter.PositiveInfinity < (quarter3)quarter.NaN).x); + Assert.IsFalse(((quarter3)quarter.NegativeInfinity < (quarter3)quarter.NaN).x); + + for (int i = 0; i < 25; i++) + { + quarter3 lhs = (quarter3)rng.NextFloat3(quarter.MinValue, quarter.MaxValue); + quarter3 rhs = (quarter3)rng.NextFloat3(quarter.MinValue, quarter.MaxValue); + + Assert.AreEqual(lhs < rhs, (float3)lhs < (float3)rhs); + Assert.AreEqual(lhs < lhs, (float3)lhs < (float3)lhs); + + lhs = (quarter3)0f; + + Assert.AreEqual(lhs < rhs, (float3)lhs < (float3)rhs); + Assert.AreEqual(lhs < lhs, (float3)lhs < (float3)lhs); + } + } + + [Test] + public static void LessEqual3() + { + Random32 rng = Random32.New; + + Assert.IsFalse(((quarter3)quarter.NaN <= (quarter3)0f).x); + Assert.IsFalse(((quarter3)0f <= (quarter3)quarter.NaN).x); + Assert.IsFalse(((quarter3)quarter.PositiveInfinity <= (quarter3)quarter.NaN).x); + Assert.IsFalse(((quarter3)quarter.NegativeInfinity <= (quarter3)quarter.NaN).x); + + for (int i = 0; i < 35; i++) + { + quarter3 lhs = (quarter3)rng.NextFloat3(quarter.MinValue, quarter.MaxValue); + quarter3 rhs = (quarter3)rng.NextFloat3(quarter.MinValue, quarter.MaxValue); + + Assert.AreEqual(lhs <= rhs, (float3)lhs <= (float3)rhs); + Assert.AreEqual(lhs <= lhs, (float3)lhs <= (float3)lhs); + + lhs = (quarter3)0f; + + Assert.AreEqual(lhs < rhs, (float3)lhs < (float3)rhs); + Assert.AreEqual(lhs < lhs, (float3)lhs < (float3)lhs); + } + } [Test] @@ -1233,6 +1363,56 @@ public static void NotEquals4() Assert.IsTrue(math.all((quarter4)(quarter)1f != (quarter)(-1f))); } + + [Test] + public static void LessThan4() + { + Random32 rng = Random32.New; + + Assert.IsFalse(((quarter4)quarter.NaN < (quarter4)0f).x); + Assert.IsFalse(((quarter4)0f < (quarter4)quarter.NaN).x); + Assert.IsFalse(((quarter4)quarter.PositiveInfinity < (quarter4)quarter.NaN).x); + Assert.IsFalse(((quarter4)quarter.NegativeInfinity < (quarter4)quarter.NaN).x); + + for (int i = 0; i < 25; i++) + { + quarter4 lhs = (quarter4)rng.NextFloat4(quarter.MinValue, quarter.MaxValue); + quarter4 rhs = (quarter4)rng.NextFloat4(quarter.MinValue, quarter.MaxValue); + + Assert.AreEqual(lhs < rhs, (float4)lhs < (float4)rhs); + Assert.AreEqual(lhs < lhs, (float4)lhs < (float4)lhs); + + lhs = (quarter4)0f; + + Assert.AreEqual(lhs < rhs, (float4)lhs < (float4)rhs); + Assert.AreEqual(lhs < lhs, (float4)lhs < (float4)lhs); + } + } + + [Test] + public static void LessEqual4() + { + Random32 rng = Random32.New; + + Assert.IsFalse(((quarter4)quarter.NaN <= (quarter4)0f).x); + Assert.IsFalse(((quarter4)0f <= (quarter4)quarter.NaN).x); + Assert.IsFalse(((quarter4)quarter.PositiveInfinity <= (quarter4)quarter.NaN).x); + Assert.IsFalse(((quarter4)quarter.NegativeInfinity <= (quarter4)quarter.NaN).x); + + for (int i = 0; i < 45; i++) + { + quarter4 lhs = (quarter4)rng.NextFloat4(quarter.MinValue, quarter.MaxValue); + quarter4 rhs = (quarter4)rng.NextFloat4(quarter.MinValue, quarter.MaxValue); + + Assert.AreEqual(lhs <= rhs, (float4)lhs <= (float4)rhs); + Assert.AreEqual(lhs <= lhs, (float4)lhs <= (float4)lhs); + + lhs = (quarter4)0f; + + Assert.AreEqual(lhs < rhs, (float4)lhs < (float4)rhs); + Assert.AreEqual(lhs < lhs, (float4)lhs < (float4)lhs); + } + } [Test] @@ -1594,6 +1774,56 @@ public static void NotEquals8() Assert.IsTrue(maxmath.all((quarter8)(quarter)1f != (quarter)(-1f))); } + [Test] + public static void LessThan8() + { + Random32 rng = Random32.New; + + Assert.IsFalse(((quarter8)quarter.NaN < (quarter8)0f).x0); + Assert.IsFalse(((quarter8)0f < (quarter8)quarter.NaN).x0); + Assert.IsFalse(((quarter8)quarter.PositiveInfinity < (quarter8)quarter.NaN).x0); + Assert.IsFalse(((quarter8)quarter.NegativeInfinity < (quarter8)quarter.NaN).x0); + + for (int i = 0; i < 25; i++) + { + quarter8 lhs = (quarter8)rng.NextFloat8(quarter.MinValue, quarter.MaxValue); + quarter8 rhs = (quarter8)rng.NextFloat8(quarter.MinValue, quarter.MaxValue); + + Assert.AreEqual(lhs < rhs, (float8)lhs < (float8)rhs); + Assert.AreEqual(lhs < lhs, (float8)lhs < (float8)lhs); + + lhs = (quarter8)0f; + + Assert.AreEqual(lhs < rhs, (float8)lhs < (float8)rhs); + Assert.AreEqual(lhs < lhs, (float8)lhs < (float8)lhs); + } + } + + [Test] + public static void LessEqual8() + { + Random32 rng = Random32.New; + + Assert.IsFalse(((quarter8)quarter.NaN <= (quarter8)0f).x0); + Assert.IsFalse(((quarter8)0f <= (quarter8)quarter.NaN).x0); + Assert.IsFalse(((quarter8)quarter.PositiveInfinity <= (quarter8)quarter.NaN).x0); + Assert.IsFalse(((quarter8)quarter.NegativeInfinity <= (quarter8)quarter.NaN).x0); + + for (int i = 0; i < 85; i++) + { + quarter8 lhs = (quarter8)rng.NextFloat8(quarter.MinValue, quarter.MaxValue); + quarter8 rhs = (quarter8)rng.NextFloat8(quarter.MinValue, quarter.MaxValue); + + Assert.AreEqual(lhs <= rhs, (float8)lhs <= (float8)rhs); + Assert.AreEqual(lhs <= lhs, (float8)lhs <= (float8)lhs); + + lhs = (quarter8)0f; + + Assert.AreEqual(lhs < rhs, (float8)lhs < (float8)rhs); + Assert.AreEqual(lhs < lhs, (float8)lhs < (float8)lhs); + } + } + [Test] diff --git a/Tests/Editor/Types/test_sbyte16.cs b/Tests/Editor/Types/test_sbyte16.cs index 0c858c4..13a5471 100644 --- a/Tests/Editor/Types/test_sbyte16.cs +++ b/Tests/Editor/Types/test_sbyte16.cs @@ -453,6 +453,24 @@ public static void Indexer() TestData_LHS[0][13] == TestData_LHS[0].x13 & TestData_LHS[0][14] == TestData_LHS[0].x14 & TestData_LHS[0][15] == TestData_LHS[0].x15, true); + + for (int i = 0; i < 16; i++) + { + sbyte16 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 16; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_sbyte2.cs b/Tests/Editor/Types/test_sbyte2.cs index 692055e..626e69f 100644 --- a/Tests/Editor/Types/test_sbyte2.cs +++ b/Tests/Editor/Types/test_sbyte2.cs @@ -62,6 +62,24 @@ public static void Indexer() { Assert.AreEqual(TestData_LHS[0][0] == TestData_LHS[0].x & TestData_LHS[0][1] == TestData_LHS[0].y, true); + + for (int i = 0; i < 2; i++) + { + sbyte2 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 2; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_sbyte3.cs b/Tests/Editor/Types/test_sbyte3.cs index 6ab9fbf..0981adc 100644 --- a/Tests/Editor/Types/test_sbyte3.cs +++ b/Tests/Editor/Types/test_sbyte3.cs @@ -92,6 +92,24 @@ public static void Indexer() Assert.AreEqual(TestData_LHS[0][0] == TestData_LHS[0].x & TestData_LHS[0][1] == TestData_LHS[0].y & TestData_LHS[0][2] == TestData_LHS[0].z, true); + + for (int i = 0; i < 3; i++) + { + sbyte3 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 3; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_sbyte32.cs b/Tests/Editor/Types/test_sbyte32.cs index 9b60520..322eba9 100644 --- a/Tests/Editor/Types/test_sbyte32.cs +++ b/Tests/Editor/Types/test_sbyte32.cs @@ -1,5 +1,4 @@ using NUnit.Framework; -using Unity.Mathematics; using Unity.Burst.Intrinsics; namespace MaxMath.Tests @@ -39,7 +38,7 @@ unsafe public static class __sbyte32 x25 = 3, x26 = 32, x27 = 21, - x28 = 0, + x28 = 13, x29 = 47, x30 = 32, x31 = 64}, @@ -558,6 +557,24 @@ public static void Indexer() TestData_LHS[0][29] == TestData_LHS[0].x29 & TestData_LHS[0][30] == TestData_LHS[0].x30 & TestData_LHS[0][31] == TestData_LHS[0].x31, true); + + for (int i = 0; i < 32; i++) + { + sbyte32 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 32; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_sbyte4.cs b/Tests/Editor/Types/test_sbyte4.cs index 4280e67..d23ef19 100644 --- a/Tests/Editor/Types/test_sbyte4.cs +++ b/Tests/Editor/Types/test_sbyte4.cs @@ -149,6 +149,24 @@ public static void Indexer() TestData_LHS[0][1] == TestData_LHS[0].y & TestData_LHS[0][2] == TestData_LHS[0].z & TestData_LHS[0][3] == TestData_LHS[0].w, true); + + for (int i = 0; i < 4; i++) + { + sbyte4 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 4; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_sbyte8.cs b/Tests/Editor/Types/test_sbyte8.cs index 73ecd68..96c4cfc 100644 --- a/Tests/Editor/Types/test_sbyte8.cs +++ b/Tests/Editor/Types/test_sbyte8.cs @@ -243,6 +243,24 @@ public static void Indexer() TestData_LHS[0][5] == TestData_LHS[0].x5 & TestData_LHS[0][6] == TestData_LHS[0].x6 & TestData_LHS[0][7] == TestData_LHS[0].x7, true); + + for (int i = 0; i < 8; i++) + { + sbyte8 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 8; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_short16.cs b/Tests/Editor/Types/test_short16.cs index 32c5a5c..c9ab54b 100644 --- a/Tests/Editor/Types/test_short16.cs +++ b/Tests/Editor/Types/test_short16.cs @@ -453,6 +453,24 @@ public static void Indexer() TestData_LHS[0][13] == TestData_LHS[0].x13 & TestData_LHS[0][14] == TestData_LHS[0].x14 & TestData_LHS[0][15] == TestData_LHS[0].x15, true); + + for (int i = 0; i < 16; i++) + { + short16 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 16; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_short2.cs b/Tests/Editor/Types/test_short2.cs index af32d85..89b6c85 100644 --- a/Tests/Editor/Types/test_short2.cs +++ b/Tests/Editor/Types/test_short2.cs @@ -62,6 +62,24 @@ public static void Indexer() { Assert.AreEqual(TestData_LHS[0][0] == TestData_LHS[0].x & TestData_LHS[0][1] == TestData_LHS[0].y, true); + + for (int i = 0; i < 2; i++) + { + short2 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 2; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_short3.cs b/Tests/Editor/Types/test_short3.cs index 119562c..32ebd52 100644 --- a/Tests/Editor/Types/test_short3.cs +++ b/Tests/Editor/Types/test_short3.cs @@ -92,6 +92,24 @@ public static void Indexer() Assert.AreEqual(TestData_LHS[0][0] == TestData_LHS[0].x & TestData_LHS[0][1] == TestData_LHS[0].y & TestData_LHS[0][2] == TestData_LHS[0].z, true); + + for (int i = 0; i < 3; i++) + { + short3 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 3; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_short4.cs b/Tests/Editor/Types/test_short4.cs index c32f13c..1b96794 100644 --- a/Tests/Editor/Types/test_short4.cs +++ b/Tests/Editor/Types/test_short4.cs @@ -149,6 +149,24 @@ public static void Indexer() TestData_LHS[0][1] == TestData_LHS[0].y & TestData_LHS[0][2] == TestData_LHS[0].z & TestData_LHS[0][3] == TestData_LHS[0].w, true); + + for (int i = 0; i < 4; i++) + { + short4 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 4; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_short8.cs b/Tests/Editor/Types/test_short8.cs index 9940669..e952eee 100644 --- a/Tests/Editor/Types/test_short8.cs +++ b/Tests/Editor/Types/test_short8.cs @@ -243,6 +243,24 @@ public static void Indexer() TestData_LHS[0][5] == TestData_LHS[0].x5 & TestData_LHS[0][6] == TestData_LHS[0].x6 & TestData_LHS[0][7] == TestData_LHS[0].x7, true); + + for (int i = 0; i < 8; i++) + { + short8 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 8; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_uint128.cs b/Tests/Editor/Types/test_uint128.cs index e49de08..6550a71 100644 --- a/Tests/Editor/Types/test_uint128.cs +++ b/Tests/Editor/Types/test_uint128.cs @@ -1181,5 +1181,29 @@ public static void CONST2_MultiplyUInt128() (BigInteger)(left * right)); } } + + + [Test] + new public static void ToString() + { + Random128 rng = Random128.New; + UInt128 x = 0; + + Assert.AreEqual(UInt128.MAX_DECIMAL_DIGITS, ((BigInteger)UInt128.MaxValue).ToString().Length); + Assert.AreEqual(x.ToString(), "0"); + Assert.AreEqual(UInt128.MaxValue.ToString(), ((BigInteger)UInt128.MaxValue).ToString()); + + for (int i = 0; i < 25; i++) + { + x = rng.NextUInt128(); + Assert.AreEqual(x.ToString(), ((BigInteger)x).ToString()); + + x = rng.NextUInt128(0, uint.MaxValue); + Assert.AreEqual(x.ToString(), ((BigInteger)x).ToString()); + + x = rng.NextUInt128(0, 10); + Assert.AreEqual(x.ToString(), ((BigInteger)x).ToString()); + } + } } } \ No newline at end of file diff --git a/Tests/Editor/Types/test_uint8.cs b/Tests/Editor/Types/test_uint8.cs index 9a440cb..a4c2e4d 100644 --- a/Tests/Editor/Types/test_uint8.cs +++ b/Tests/Editor/Types/test_uint8.cs @@ -243,6 +243,24 @@ public static void Indexer() TestData_LHS[0][5] == TestData_LHS[0].x5 & TestData_LHS[0][6] == TestData_LHS[0].x6 & TestData_LHS[0][7] == TestData_LHS[0].x7, true); + + for (int i = 0; i < 8; i++) + { + uint8 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 8; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_ulong2.cs b/Tests/Editor/Types/test_ulong2.cs index 1b7373b..7aaa26f 100644 --- a/Tests/Editor/Types/test_ulong2.cs +++ b/Tests/Editor/Types/test_ulong2.cs @@ -62,6 +62,24 @@ public static void Indexer() { Assert.AreEqual(TestData_LHS[0][0] == TestData_LHS[0].x & TestData_LHS[0][1] == TestData_LHS[0].y, true); + + for (int i = 0; i < 2; i++) + { + ulong2 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 2; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_ulong3.cs b/Tests/Editor/Types/test_ulong3.cs index d838947..ba5ce78 100644 --- a/Tests/Editor/Types/test_ulong3.cs +++ b/Tests/Editor/Types/test_ulong3.cs @@ -92,6 +92,24 @@ public static void Indexer() Assert.AreEqual(TestData_LHS[0][0] == TestData_LHS[0].x & TestData_LHS[0][1] == TestData_LHS[0].y & TestData_LHS[0][2] == TestData_LHS[0].z, true); + + for (int i = 0; i < 3; i++) + { + ulong3 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 3; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_ulong4.cs b/Tests/Editor/Types/test_ulong4.cs index 91efe94..9ad40fb 100644 --- a/Tests/Editor/Types/test_ulong4.cs +++ b/Tests/Editor/Types/test_ulong4.cs @@ -149,6 +149,24 @@ public static void Indexer() TestData_LHS[0][1] == TestData_LHS[0].y & TestData_LHS[0][2] == TestData_LHS[0].z & TestData_LHS[0][3] == TestData_LHS[0].w, true); + + for (int i = 0; i < 4; i++) + { + ulong4 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 4; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_ushort16.cs b/Tests/Editor/Types/test_ushort16.cs index e646403..ff66f80 100644 --- a/Tests/Editor/Types/test_ushort16.cs +++ b/Tests/Editor/Types/test_ushort16.cs @@ -453,6 +453,24 @@ public static void Indexer() TestData_LHS[0][13] == TestData_LHS[0].x13 & TestData_LHS[0][14] == TestData_LHS[0].x14 & TestData_LHS[0][15] == TestData_LHS[0].x15, true); + + for (int i = 0; i < 16; i++) + { + ushort16 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 16; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_ushort2.cs b/Tests/Editor/Types/test_ushort2.cs index a191713..fe87634 100644 --- a/Tests/Editor/Types/test_ushort2.cs +++ b/Tests/Editor/Types/test_ushort2.cs @@ -62,6 +62,24 @@ public static void Indexer() { Assert.AreEqual(TestData_LHS[0][0] == TestData_LHS[0].x & TestData_LHS[0][1] == TestData_LHS[0].y, true); + + for (int i = 0; i < 2; i++) + { + ushort2 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 2; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_ushort3.cs b/Tests/Editor/Types/test_ushort3.cs index 3c87f36..0eb9a9e 100644 --- a/Tests/Editor/Types/test_ushort3.cs +++ b/Tests/Editor/Types/test_ushort3.cs @@ -92,6 +92,24 @@ public static void Indexer() Assert.AreEqual(TestData_LHS[0][0] == TestData_LHS[0].x & TestData_LHS[0][1] == TestData_LHS[0].y & TestData_LHS[0][2] == TestData_LHS[0].z, true); + + for (int i = 0; i < 3; i++) + { + ushort3 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 3; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_ushort4.cs b/Tests/Editor/Types/test_ushort4.cs index 1840540..a17e27c 100644 --- a/Tests/Editor/Types/test_ushort4.cs +++ b/Tests/Editor/Types/test_ushort4.cs @@ -149,6 +149,24 @@ public static void Indexer() TestData_LHS[0][1] == TestData_LHS[0].y & TestData_LHS[0][2] == TestData_LHS[0].z & TestData_LHS[0][3] == TestData_LHS[0].w, true); + + for (int i = 0; i < 4; i++) + { + ushort4 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 4; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/Tests/Editor/Types/test_ushort8.cs b/Tests/Editor/Types/test_ushort8.cs index 52d46b2..5443414 100644 --- a/Tests/Editor/Types/test_ushort8.cs +++ b/Tests/Editor/Types/test_ushort8.cs @@ -243,6 +243,24 @@ public static void Indexer() TestData_LHS[0][5] == TestData_LHS[0].x5 & TestData_LHS[0][6] == TestData_LHS[0].x6 & TestData_LHS[0][7] == TestData_LHS[0].x7, true); + + for (int i = 0; i < 8; i++) + { + ushort8 x = TestData_LHS[0]; + + x[i] = 0; + Assert.AreEqual(x[i], 0); + + for (int j = 0; j < i; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + + for (int j = i + 1; j < 8; j++) + { + Assert.AreEqual(x[j], TestData_LHS[0][j]); + } + } } diff --git a/manifest.json b/manifest.json index df27d65..6153553 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "maxmath", "displayName": "MaxMath", - "version": "2.3.0", + "version": "2.3.5", "unity": "2018.4", "description": "MaxMath is SIMD math library, supplementary to Unity.Mathematics using Unity.Burst. It adds (s)byte, (u)short and (u)long SIMD vectors and matrices to the ones already provided by Unity.Mathematics. Almost all functions present in Unity.Mathematics have been transcribed to work with the new vector and matrix types in addition to many useful functions having been added.", "keywords": [ diff --git a/package.json b/package.json index 756151b..627e172 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "maxmath", "displayName": "MaxMath", - "version": "2.3.0", + "version": "2.3.5", "unity": "2018.4", "description": "MaxMath is SIMD math library, supplementary to Unity.Mathematics using Unity.Burst. It adds (s)byte, (u)short and (u)long SIMD vectors and matrices to the ones already provided by Unity.Mathematics. Almost all functions present in Unity.Mathematics have been transcribed to work with the new vector and matrix types in addition to many useful functions having been added.", "keywords": [