aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Instructions/VectorHelper.cs
diff options
context:
space:
mode:
authorAlex Barney <thealexbarney@gmail.com>2018-10-30 19:43:02 -0600
committergdkchan <gab.dark.100@gmail.com>2018-10-30 22:43:02 -0300
commit9cb57fb4bb3bbae0ae052a5af4a96a49fc5d864d (patch)
tree0c97425aeb311c142bc92a6fcc503cb2c07d4376 /ChocolArm64/Instructions/VectorHelper.cs
parent5a87e58183578f5b84ca8d01cbb76aed11820f78 (diff)
Adjust naming conventions for Ryujinx and ChocolArm64 projects (#484)
* Change naming convention for Ryujinx project * Change naming convention for ChocolArm64 project * Fix NaN * Remove unneeded this. from Ryujinx project * Adjust naming from new PRs * Name changes based on feedback * How did this get removed? * Rebasing fix * Change FP enum case * Remove prefix from ChocolArm64 classes - Part 1 * Remove prefix from ChocolArm64 classes - Part 2 * Fix alignment from last commit's renaming * Rename namespaces * Rename stragglers * Fix alignment * Rename OpCode class * Missed a few * Adjust alignment
Diffstat (limited to 'ChocolArm64/Instructions/VectorHelper.cs')
-rw-r--r--ChocolArm64/Instructions/VectorHelper.cs790
1 files changed, 790 insertions, 0 deletions
diff --git a/ChocolArm64/Instructions/VectorHelper.cs b/ChocolArm64/Instructions/VectorHelper.cs
new file mode 100644
index 00000000..8ef15818
--- /dev/null
+++ b/ChocolArm64/Instructions/VectorHelper.cs
@@ -0,0 +1,790 @@
+using ChocolArm64.State;
+using ChocolArm64.Translation;
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace ChocolArm64.Instructions
+{
+ static class VectorHelper
+ {
+ private static readonly Vector128<float> Zero32128Mask;
+
+ static VectorHelper()
+ {
+ if (!Sse2.IsSupported)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ Zero32128Mask = Sse.StaticCast<uint, float>(Sse2.SetVector128(0, 0, 0, 0xffffffff));
+ }
+
+ public static void EmitCall(ILEmitterCtx context, string name64, string name128)
+ {
+ bool isSimd64 = context.CurrOp.RegisterSize == RegisterSize.Simd64;
+
+ context.EmitCall(typeof(VectorHelper), isSimd64 ? name64 : name128);
+ }
+
+ public static void EmitCall(ILEmitterCtx context, string mthdName)
+ {
+ context.EmitCall(typeof(VectorHelper), mthdName);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int SatF32ToS32(float value)
+ {
+ if (float.IsNaN(value)) return 0;
+
+ return value > int.MaxValue ? int.MaxValue :
+ value < int.MinValue ? int.MinValue : (int)value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static long SatF32ToS64(float value)
+ {
+ if (float.IsNaN(value)) return 0;
+
+ return value > long.MaxValue ? long.MaxValue :
+ value < long.MinValue ? long.MinValue : (long)value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static uint SatF32ToU32(float value)
+ {
+ if (float.IsNaN(value)) return 0;
+
+ return value > uint.MaxValue ? uint.MaxValue :
+ value < uint.MinValue ? uint.MinValue : (uint)value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ulong SatF32ToU64(float value)
+ {
+ if (float.IsNaN(value)) return 0;
+
+ return value > ulong.MaxValue ? ulong.MaxValue :
+ value < ulong.MinValue ? ulong.MinValue : (ulong)value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int SatF64ToS32(double value)
+ {
+ if (double.IsNaN(value)) return 0;
+
+ return value > int.MaxValue ? int.MaxValue :
+ value < int.MinValue ? int.MinValue : (int)value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static long SatF64ToS64(double value)
+ {
+ if (double.IsNaN(value)) return 0;
+
+ return value > long.MaxValue ? long.MaxValue :
+ value < long.MinValue ? long.MinValue : (long)value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static uint SatF64ToU32(double value)
+ {
+ if (double.IsNaN(value)) return 0;
+
+ return value > uint.MaxValue ? uint.MaxValue :
+ value < uint.MinValue ? uint.MinValue : (uint)value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ulong SatF64ToU64(double value)
+ {
+ if (double.IsNaN(value)) return 0;
+
+ return value > ulong.MaxValue ? ulong.MaxValue :
+ value < ulong.MinValue ? ulong.MinValue : (ulong)value;
+ }
+
+ public static double Round(double value, CpuThreadState state)
+ {
+ switch (state.FPRoundingMode())
+ {
+ case RoundMode.ToNearest: return Math.Round (value);
+ case RoundMode.TowardsPlusInfinity: return Math.Ceiling (value);
+ case RoundMode.TowardsMinusInfinity: return Math.Floor (value);
+ case RoundMode.TowardsZero: return Math.Truncate(value);
+ }
+
+ throw new InvalidOperationException();
+ }
+
+ public static float RoundF(float value, CpuThreadState state)
+ {
+ switch (state.FPRoundingMode())
+ {
+ case RoundMode.ToNearest: return MathF.Round (value);
+ case RoundMode.TowardsPlusInfinity: return MathF.Ceiling (value);
+ case RoundMode.TowardsMinusInfinity: return MathF.Floor (value);
+ case RoundMode.TowardsZero: return MathF.Truncate(value);
+ }
+
+ throw new InvalidOperationException();
+ }
+
+ public static Vector128<float> Tbl1_V64(
+ Vector128<float> vector,
+ Vector128<float> tb0)
+ {
+ return Tbl(vector, 8, tb0);
+ }
+
+ public static Vector128<float> Tbl1_V128(
+ Vector128<float> vector,
+ Vector128<float> tb0)
+ {
+ return Tbl(vector, 16, tb0);
+ }
+
+ public static Vector128<float> Tbl2_V64(
+ Vector128<float> vector,
+ Vector128<float> tb0,
+ Vector128<float> tb1)
+ {
+ return Tbl(vector, 8, tb0, tb1);
+ }
+
+ public static Vector128<float> Tbl2_V128(
+ Vector128<float> vector,
+ Vector128<float> tb0,
+ Vector128<float> tb1)
+ {
+ return Tbl(vector, 16, tb0, tb1);
+ }
+
+ public static Vector128<float> Tbl3_V64(
+ Vector128<float> vector,
+ Vector128<float> tb0,
+ Vector128<float> tb1,
+ Vector128<float> tb2)
+ {
+ return Tbl(vector, 8, tb0, tb1, tb2);
+ }
+
+ public static Vector128<float> Tbl3_V128(
+ Vector128<float> vector,
+ Vector128<float> tb0,
+ Vector128<float> tb1,
+ Vector128<float> tb2)
+ {
+ return Tbl(vector, 16, tb0, tb1, tb2);
+ }
+
+ public static Vector128<float> Tbl4_V64(
+ Vector128<float> vector,
+ Vector128<float> tb0,
+ Vector128<float> tb1,
+ Vector128<float> tb2,
+ Vector128<float> tb3)
+ {
+ return Tbl(vector, 8, tb0, tb1, tb2, tb3);
+ }
+
+ public static Vector128<float> Tbl4_V128(
+ Vector128<float> vector,
+ Vector128<float> tb0,
+ Vector128<float> tb1,
+ Vector128<float> tb2,
+ Vector128<float> tb3)
+ {
+ return Tbl(vector, 16, tb0, tb1, tb2, tb3);
+ }
+
+ private static Vector128<float> Tbl(Vector128<float> vector, int bytes, params Vector128<float>[] tb)
+ {
+ Vector128<float> res = new Vector128<float>();
+
+ byte[] table = new byte[tb.Length * 16];
+
+ for (byte index = 0; index < tb.Length; index++)
+ for (byte index2 = 0; index2 < 16; index2++)
+ {
+ table[index * 16 + index2] = (byte)VectorExtractIntZx(tb[index], index2, 0);
+ }
+
+ for (byte index = 0; index < bytes; index++)
+ {
+ byte tblIdx = (byte)VectorExtractIntZx(vector, index, 0);
+
+ if (tblIdx < table.Length)
+ {
+ res = VectorInsertInt(table[tblIdx], res, index, 0);
+ }
+ }
+
+ return res;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double VectorExtractDouble(Vector128<float> vector, byte index)
+ {
+ if (Sse41.IsSupported)
+ {
+ return BitConverter.Int64BitsToDouble(Sse41.Extract(Sse.StaticCast<float, long>(vector), index));
+ }
+ else if (Sse2.IsSupported)
+ {
+ return BitConverter.Int64BitsToDouble((long)VectorExtractIntZx(vector, index, 3));
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static long VectorExtractIntSx(Vector128<float> vector, byte index, int size)
+ {
+ if (Sse41.IsSupported)
+ {
+ if (size == 0)
+ {
+ return (sbyte)Sse41.Extract(Sse.StaticCast<float, byte>(vector), index);
+ }
+ else if (size == 1)
+ {
+ return (short)Sse2.Extract(Sse.StaticCast<float, ushort>(vector), index);
+ }
+ else if (size == 2)
+ {
+ return Sse41.Extract(Sse.StaticCast<float, int>(vector), index);
+ }
+ else if (size == 3)
+ {
+ return Sse41.Extract(Sse.StaticCast<float, long>(vector), index);
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(nameof(size));
+ }
+ }
+ else if (Sse2.IsSupported)
+ {
+ if (size == 0)
+ {
+ return (sbyte)VectorExtractIntZx(vector, index, size);
+ }
+ else if (size == 1)
+ {
+ return (short)VectorExtractIntZx(vector, index, size);
+ }
+ else if (size == 2)
+ {
+ return (int)VectorExtractIntZx(vector, index, size);
+ }
+ else if (size == 3)
+ {
+ return (long)VectorExtractIntZx(vector, index, size);
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(nameof(size));
+ }
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ulong VectorExtractIntZx(Vector128<float> vector, byte index, int size)
+ {
+ if (Sse41.IsSupported)
+ {
+ if (size == 0)
+ {
+ return Sse41.Extract(Sse.StaticCast<float, byte>(vector), index);
+ }
+ else if (size == 1)
+ {
+ return Sse2.Extract(Sse.StaticCast<float, ushort>(vector), index);
+ }
+ else if (size == 2)
+ {
+ return Sse41.Extract(Sse.StaticCast<float, uint>(vector), index);
+ }
+ else if (size == 3)
+ {
+ return Sse41.Extract(Sse.StaticCast<float, ulong>(vector), index);
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(nameof(size));
+ }
+ }
+ else if (Sse2.IsSupported)
+ {
+ int shortIdx = size == 0
+ ? index >> 1
+ : index << (size - 1);
+
+ ushort value = Sse2.Extract(Sse.StaticCast<float, ushort>(vector), (byte)shortIdx);
+
+ if (size == 0)
+ {
+ return (byte)(value >> (index & 1) * 8);
+ }
+ else if (size == 1)
+ {
+ return value;
+ }
+ else if (size == 2 || size == 3)
+ {
+ ushort value1 = Sse2.Extract(Sse.StaticCast<float, ushort>(vector), (byte)(shortIdx + 1));
+
+ if (size == 2)
+ {
+ return (uint)(value | (value1 << 16));
+ }
+
+ ushort value2 = Sse2.Extract(Sse.StaticCast<float, ushort>(vector), (byte)(shortIdx + 2));
+ ushort value3 = Sse2.Extract(Sse.StaticCast<float, ushort>(vector), (byte)(shortIdx + 3));
+
+ return ((ulong)value << 0) |
+ ((ulong)value1 << 16) |
+ ((ulong)value2 << 32) |
+ ((ulong)value3 << 48);
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(nameof(size));
+ }
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float VectorExtractSingle(Vector128<float> vector, byte index)
+ {
+ if (Sse41.IsSupported)
+ {
+ return Sse41.Extract(vector, index);
+ }
+ else if (Sse2.IsSupported)
+ {
+ Vector128<ushort> shortVector = Sse.StaticCast<float, ushort>(vector);
+
+ int low = Sse2.Extract(shortVector, (byte)(index * 2 + 0));
+ int high = Sse2.Extract(shortVector, (byte)(index * 2 + 1));
+
+ return BitConverter.Int32BitsToSingle(low | (high << 16));
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<float> VectorInsertDouble(double value, Vector128<float> vector, byte index)
+ {
+ return VectorInsertInt((ulong)BitConverter.DoubleToInt64Bits(value), vector, index, 3);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<float> VectorInsertInt(ulong value, Vector128<float> vector, byte index, int size)
+ {
+ if (Sse41.IsSupported)
+ {
+ if (size == 0)
+ {
+ return Sse.StaticCast<byte, float>(Sse41.Insert(Sse.StaticCast<float, byte>(vector), (byte)value, index));
+ }
+ else if (size == 1)
+ {
+ return Sse.StaticCast<ushort, float>(Sse2.Insert(Sse.StaticCast<float, ushort>(vector), (ushort)value, index));
+ }
+ else if (size == 2)
+ {
+ return Sse.StaticCast<uint, float>(Sse41.Insert(Sse.StaticCast<float, uint>(vector), (uint)value, index));
+ }
+ else if (size == 3)
+ {
+ return Sse.StaticCast<ulong, float>(Sse41.Insert(Sse.StaticCast<float, ulong>(vector), value, index));
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(nameof(size));
+ }
+ }
+ else if (Sse2.IsSupported)
+ {
+ Vector128<ushort> shortVector = Sse.StaticCast<float, ushort>(vector);
+
+ int shortIdx = size == 0
+ ? index >> 1
+ : index << (size - 1);
+
+ if (size == 0)
+ {
+ ushort shortVal = Sse2.Extract(Sse.StaticCast<float, ushort>(vector), (byte)shortIdx);
+
+ int shift = (index & 1) * 8;
+
+ shortVal &= (ushort)(0xff00 >> shift);
+
+ shortVal |= (ushort)((byte)value << shift);
+
+ return Sse.StaticCast<ushort, float>(Sse2.Insert(shortVector, shortVal, (byte)shortIdx));
+ }
+ else if (size == 1)
+ {
+ return Sse.StaticCast<ushort, float>(Sse2.Insert(Sse.StaticCast<float, ushort>(vector), (ushort)value, index));
+ }
+ else if (size == 2 || size == 3)
+ {
+ shortVector = Sse2.Insert(shortVector, (ushort)(value >> 0), (byte)(shortIdx + 0));
+ shortVector = Sse2.Insert(shortVector, (ushort)(value >> 16), (byte)(shortIdx + 1));
+
+ if (size == 3)
+ {
+ shortVector = Sse2.Insert(shortVector, (ushort)(value >> 32), (byte)(shortIdx + 2));
+ shortVector = Sse2.Insert(shortVector, (ushort)(value >> 48), (byte)(shortIdx + 3));
+ }
+
+ return Sse.StaticCast<ushort, float>(shortVector);
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(nameof(size));
+ }
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<float> VectorInsertSingle(float value, Vector128<float> vector, byte index)
+ {
+ if (Sse41.IsSupported)
+ {
+ //Note: The if/else if is necessary to enable the JIT to
+ //produce a single INSERTPS instruction instead of the
+ //jump table fallback.
+ if (index == 0)
+ {
+ return Sse41.Insert(vector, value, 0x00);
+ }
+ else if (index == 1)
+ {
+ return Sse41.Insert(vector, value, 0x10);
+ }
+ else if (index == 2)
+ {
+ return Sse41.Insert(vector, value, 0x20);
+ }
+ else if (index == 3)
+ {
+ return Sse41.Insert(vector, value, 0x30);
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ }
+ else if (Sse2.IsSupported)
+ {
+ int intValue = BitConverter.SingleToInt32Bits(value);
+
+ ushort low = (ushort)(intValue >> 0);
+ ushort high = (ushort)(intValue >> 16);
+
+ Vector128<ushort> shortVector = Sse.StaticCast<float, ushort>(vector);
+
+ shortVector = Sse2.Insert(shortVector, low, (byte)(index * 2 + 0));
+ shortVector = Sse2.Insert(shortVector, high, (byte)(index * 2 + 1));
+
+ return Sse.StaticCast<ushort, float>(shortVector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<float> Sse41VectorInsertScalarSingle(float value, Vector128<float> vector)
+ {
+ //Note: 0b1110 is the mask to zero the upper bits.
+ return Sse41.Insert(vector, value, 0b1110);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<sbyte> VectorSByteZero()
+ {
+ if (Sse2.IsSupported)
+ {
+ return Sse2.SetZeroVector128<sbyte>();
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<short> VectorInt16Zero()
+ {
+ if (Sse2.IsSupported)
+ {
+ return Sse2.SetZeroVector128<short>();
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<int> VectorInt32Zero()
+ {
+ if (Sse2.IsSupported)
+ {
+ return Sse2.SetZeroVector128<int>();
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<long> VectorInt64Zero()
+ {
+ if (Sse2.IsSupported)
+ {
+ return Sse2.SetZeroVector128<long>();
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<float> VectorSingleZero()
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.SetZeroVector128();
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<double> VectorDoubleZero()
+ {
+ if (Sse2.IsSupported)
+ {
+ return Sse2.SetZeroVector128<double>();
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<float> VectorZero32_128(Vector128<float> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.And(vector, Zero32128Mask);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<sbyte> VectorSingleToSByte(Vector128<float> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<float, sbyte>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<short> VectorSingleToInt16(Vector128<float> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<float, short>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<int> VectorSingleToInt32(Vector128<float> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<float, int>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<long> VectorSingleToInt64(Vector128<float> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<float, long>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<byte> VectorSingleToByte(Vector128<float> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<float, byte>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<ushort> VectorSingleToUInt16(Vector128<float> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<float, ushort>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<uint> VectorSingleToUInt32(Vector128<float> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<float, uint>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<ulong> VectorSingleToUInt64(Vector128<float> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<float, ulong>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<double> VectorSingleToDouble(Vector128<float> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<float, double>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<float> VectorSByteToSingle(Vector128<sbyte> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<sbyte, float>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<float> VectorInt16ToSingle(Vector128<short> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<short, float>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<float> VectorInt32ToSingle(Vector128<int> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<int, float>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<float> VectorInt64ToSingle(Vector128<long> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<long, float>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<float> VectorByteToSingle(Vector128<byte> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<byte, float>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<float> VectorUInt16ToSingle(Vector128<ushort> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<ushort, float>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<float> VectorUInt32ToSingle(Vector128<uint> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<uint, float>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<float> VectorUInt64ToSingle(Vector128<ulong> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<ulong, float>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<float> VectorDoubleToSingle(Vector128<double> vector)
+ {
+ if (Sse.IsSupported)
+ {
+ return Sse.StaticCast<double, float>(vector);
+ }
+
+ throw new PlatformNotSupportedException();
+ }
+ }
+}