AVectorHelper.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. using ChocolArm64.State;
  2. using ChocolArm64.Translation;
  3. using System;
  4. using System.Runtime.CompilerServices;
  5. using System.Runtime.Intrinsics;
  6. using System.Runtime.Intrinsics.X86;
  7. namespace ChocolArm64.Instruction
  8. {
  9. static class AVectorHelper
  10. {
  11. private static readonly Vector128<float> Zero32_128Mask;
  12. static AVectorHelper()
  13. {
  14. if (!Sse2.IsSupported)
  15. {
  16. throw new PlatformNotSupportedException();
  17. }
  18. Zero32_128Mask = Sse.StaticCast<uint, float>(Sse2.SetVector128(0, 0, 0, 0xffffffff));
  19. }
  20. public static void EmitCall(AILEmitterCtx Context, string Name64, string Name128)
  21. {
  22. bool IsSimd64 = Context.CurrOp.RegisterSize == ARegisterSize.SIMD64;
  23. Context.EmitCall(typeof(AVectorHelper), IsSimd64 ? Name64 : Name128);
  24. }
  25. public static void EmitCall(AILEmitterCtx Context, string MthdName)
  26. {
  27. Context.EmitCall(typeof(AVectorHelper), MthdName);
  28. }
  29. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  30. public static int SatF32ToS32(float Value)
  31. {
  32. if (float.IsNaN(Value)) return 0;
  33. return Value > int.MaxValue ? int.MaxValue :
  34. Value < int.MinValue ? int.MinValue : (int)Value;
  35. }
  36. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  37. public static long SatF32ToS64(float Value)
  38. {
  39. if (float.IsNaN(Value)) return 0;
  40. return Value > long.MaxValue ? long.MaxValue :
  41. Value < long.MinValue ? long.MinValue : (long)Value;
  42. }
  43. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  44. public static uint SatF32ToU32(float Value)
  45. {
  46. if (float.IsNaN(Value)) return 0;
  47. return Value > uint.MaxValue ? uint.MaxValue :
  48. Value < uint.MinValue ? uint.MinValue : (uint)Value;
  49. }
  50. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  51. public static ulong SatF32ToU64(float Value)
  52. {
  53. if (float.IsNaN(Value)) return 0;
  54. return Value > ulong.MaxValue ? ulong.MaxValue :
  55. Value < ulong.MinValue ? ulong.MinValue : (ulong)Value;
  56. }
  57. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  58. public static int SatF64ToS32(double Value)
  59. {
  60. if (double.IsNaN(Value)) return 0;
  61. return Value > int.MaxValue ? int.MaxValue :
  62. Value < int.MinValue ? int.MinValue : (int)Value;
  63. }
  64. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  65. public static long SatF64ToS64(double Value)
  66. {
  67. if (double.IsNaN(Value)) return 0;
  68. return Value > long.MaxValue ? long.MaxValue :
  69. Value < long.MinValue ? long.MinValue : (long)Value;
  70. }
  71. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  72. public static uint SatF64ToU32(double Value)
  73. {
  74. if (double.IsNaN(Value)) return 0;
  75. return Value > uint.MaxValue ? uint.MaxValue :
  76. Value < uint.MinValue ? uint.MinValue : (uint)Value;
  77. }
  78. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  79. public static ulong SatF64ToU64(double Value)
  80. {
  81. if (double.IsNaN(Value)) return 0;
  82. return Value > ulong.MaxValue ? ulong.MaxValue :
  83. Value < ulong.MinValue ? ulong.MinValue : (ulong)Value;
  84. }
  85. public static double Round(double Value, AThreadState State)
  86. {
  87. switch (State.FPRoundingMode())
  88. {
  89. case ARoundMode.ToNearest: return Math.Round (Value);
  90. case ARoundMode.TowardsPlusInfinity: return Math.Ceiling (Value);
  91. case ARoundMode.TowardsMinusInfinity: return Math.Floor (Value);
  92. case ARoundMode.TowardsZero: return Math.Truncate(Value);
  93. }
  94. throw new InvalidOperationException();
  95. }
  96. public static float RoundF(float Value, AThreadState State)
  97. {
  98. switch (State.FPRoundingMode())
  99. {
  100. case ARoundMode.ToNearest: return MathF.Round (Value);
  101. case ARoundMode.TowardsPlusInfinity: return MathF.Ceiling (Value);
  102. case ARoundMode.TowardsMinusInfinity: return MathF.Floor (Value);
  103. case ARoundMode.TowardsZero: return MathF.Truncate(Value);
  104. }
  105. throw new InvalidOperationException();
  106. }
  107. public static Vector128<float> Tbl1_V64(
  108. Vector128<float> Vector,
  109. Vector128<float> Tb0)
  110. {
  111. return Tbl(Vector, 8, Tb0);
  112. }
  113. public static Vector128<float> Tbl1_V128(
  114. Vector128<float> Vector,
  115. Vector128<float> Tb0)
  116. {
  117. return Tbl(Vector, 16, Tb0);
  118. }
  119. public static Vector128<float> Tbl2_V64(
  120. Vector128<float> Vector,
  121. Vector128<float> Tb0,
  122. Vector128<float> Tb1)
  123. {
  124. return Tbl(Vector, 8, Tb0, Tb1);
  125. }
  126. public static Vector128<float> Tbl2_V128(
  127. Vector128<float> Vector,
  128. Vector128<float> Tb0,
  129. Vector128<float> Tb1)
  130. {
  131. return Tbl(Vector, 16, Tb0, Tb1);
  132. }
  133. public static Vector128<float> Tbl3_V64(
  134. Vector128<float> Vector,
  135. Vector128<float> Tb0,
  136. Vector128<float> Tb1,
  137. Vector128<float> Tb2)
  138. {
  139. return Tbl(Vector, 8, Tb0, Tb1, Tb2);
  140. }
  141. public static Vector128<float> Tbl3_V128(
  142. Vector128<float> Vector,
  143. Vector128<float> Tb0,
  144. Vector128<float> Tb1,
  145. Vector128<float> Tb2)
  146. {
  147. return Tbl(Vector, 16, Tb0, Tb1, Tb2);
  148. }
  149. public static Vector128<float> Tbl4_V64(
  150. Vector128<float> Vector,
  151. Vector128<float> Tb0,
  152. Vector128<float> Tb1,
  153. Vector128<float> Tb2,
  154. Vector128<float> Tb3)
  155. {
  156. return Tbl(Vector, 8, Tb0, Tb1, Tb2, Tb3);
  157. }
  158. public static Vector128<float> Tbl4_V128(
  159. Vector128<float> Vector,
  160. Vector128<float> Tb0,
  161. Vector128<float> Tb1,
  162. Vector128<float> Tb2,
  163. Vector128<float> Tb3)
  164. {
  165. return Tbl(Vector, 16, Tb0, Tb1, Tb2, Tb3);
  166. }
  167. private static Vector128<float> Tbl(Vector128<float> Vector, int Bytes, params Vector128<float>[] Tb)
  168. {
  169. Vector128<float> Res = new Vector128<float>();
  170. byte[] Table = new byte[Tb.Length * 16];
  171. for (byte Index = 0; Index < Tb.Length; Index++)
  172. for (byte Index2 = 0; Index2 < 16; Index2++)
  173. {
  174. Table[Index * 16 + Index2] = (byte)VectorExtractIntZx(Tb[Index], Index2, 0);
  175. }
  176. for (byte Index = 0; Index < Bytes; Index++)
  177. {
  178. byte TblIdx = (byte)VectorExtractIntZx(Vector, Index, 0);
  179. if (TblIdx < Table.Length)
  180. {
  181. Res = VectorInsertInt(Table[TblIdx], Res, Index, 0);
  182. }
  183. }
  184. return Res;
  185. }
  186. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  187. public static double VectorExtractDouble(Vector128<float> Vector, byte Index)
  188. {
  189. if (Sse41.IsSupported)
  190. {
  191. return BitConverter.Int64BitsToDouble(Sse41.Extract(Sse.StaticCast<float, long>(Vector), Index));
  192. }
  193. else if (Sse2.IsSupported)
  194. {
  195. return BitConverter.Int64BitsToDouble((long)VectorExtractIntZx(Vector, Index, 3));
  196. }
  197. throw new PlatformNotSupportedException();
  198. }
  199. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  200. public static long VectorExtractIntSx(Vector128<float> Vector, byte Index, int Size)
  201. {
  202. if (Sse41.IsSupported)
  203. {
  204. if (Size == 0)
  205. {
  206. return (sbyte)Sse41.Extract(Sse.StaticCast<float, byte>(Vector), Index);
  207. }
  208. else if (Size == 1)
  209. {
  210. return (short)Sse2.Extract(Sse.StaticCast<float, ushort>(Vector), Index);
  211. }
  212. else if (Size == 2)
  213. {
  214. return Sse41.Extract(Sse.StaticCast<float, int>(Vector), Index);
  215. }
  216. else if (Size == 3)
  217. {
  218. return Sse41.Extract(Sse.StaticCast<float, long>(Vector), Index);
  219. }
  220. else
  221. {
  222. throw new ArgumentOutOfRangeException(nameof(Size));
  223. }
  224. }
  225. else if (Sse2.IsSupported)
  226. {
  227. if (Size == 0)
  228. {
  229. return (sbyte)VectorExtractIntZx(Vector, Index, Size);
  230. }
  231. else if (Size == 1)
  232. {
  233. return (short)VectorExtractIntZx(Vector, Index, Size);
  234. }
  235. else if (Size == 2)
  236. {
  237. return (int)VectorExtractIntZx(Vector, Index, Size);
  238. }
  239. else if (Size == 3)
  240. {
  241. return (long)VectorExtractIntZx(Vector, Index, Size);
  242. }
  243. else
  244. {
  245. throw new ArgumentOutOfRangeException(nameof(Size));
  246. }
  247. }
  248. throw new PlatformNotSupportedException();
  249. }
  250. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  251. public static ulong VectorExtractIntZx(Vector128<float> Vector, byte Index, int Size)
  252. {
  253. if (Sse41.IsSupported)
  254. {
  255. if (Size == 0)
  256. {
  257. return Sse41.Extract(Sse.StaticCast<float, byte>(Vector), Index);
  258. }
  259. else if (Size == 1)
  260. {
  261. return Sse2.Extract(Sse.StaticCast<float, ushort>(Vector), Index);
  262. }
  263. else if (Size == 2)
  264. {
  265. return Sse41.Extract(Sse.StaticCast<float, uint>(Vector), Index);
  266. }
  267. else if (Size == 3)
  268. {
  269. return Sse41.Extract(Sse.StaticCast<float, ulong>(Vector), Index);
  270. }
  271. else
  272. {
  273. throw new ArgumentOutOfRangeException(nameof(Size));
  274. }
  275. }
  276. else if (Sse2.IsSupported)
  277. {
  278. int ShortIdx = Size == 0
  279. ? Index >> 1
  280. : Index << (Size - 1);
  281. ushort Value = Sse2.Extract(Sse.StaticCast<float, ushort>(Vector), (byte)ShortIdx);
  282. if (Size == 0)
  283. {
  284. return (byte)(Value >> (Index & 1) * 8);
  285. }
  286. else if (Size == 1)
  287. {
  288. return Value;
  289. }
  290. else if (Size == 2 || Size == 3)
  291. {
  292. ushort Value1 = Sse2.Extract(Sse.StaticCast<float, ushort>(Vector), (byte)(ShortIdx + 1));
  293. if (Size == 2)
  294. {
  295. return (uint)(Value | (Value1 << 16));
  296. }
  297. ushort Value2 = Sse2.Extract(Sse.StaticCast<float, ushort>(Vector), (byte)(ShortIdx + 2));
  298. ushort Value3 = Sse2.Extract(Sse.StaticCast<float, ushort>(Vector), (byte)(ShortIdx + 3));
  299. return ((ulong)Value << 0) |
  300. ((ulong)Value1 << 16) |
  301. ((ulong)Value2 << 32) |
  302. ((ulong)Value3 << 48);
  303. }
  304. else
  305. {
  306. throw new ArgumentOutOfRangeException(nameof(Size));
  307. }
  308. }
  309. throw new PlatformNotSupportedException();
  310. }
  311. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  312. public static float VectorExtractSingle(Vector128<float> Vector, byte Index)
  313. {
  314. if (Sse41.IsSupported)
  315. {
  316. return Sse41.Extract(Vector, Index);
  317. }
  318. else if (Sse2.IsSupported)
  319. {
  320. Vector128<ushort> ShortVector = Sse.StaticCast<float, ushort>(Vector);
  321. int Low = Sse2.Extract(ShortVector, (byte)(Index * 2 + 0));
  322. int High = Sse2.Extract(ShortVector, (byte)(Index * 2 + 1));
  323. return BitConverter.Int32BitsToSingle(Low | (High << 16));
  324. }
  325. throw new PlatformNotSupportedException();
  326. }
  327. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  328. public static Vector128<float> VectorInsertDouble(double Value, Vector128<float> Vector, byte Index)
  329. {
  330. return VectorInsertInt((ulong)BitConverter.DoubleToInt64Bits(Value), Vector, Index, 3);
  331. }
  332. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  333. public static Vector128<float> VectorInsertInt(ulong Value, Vector128<float> Vector, byte Index, int Size)
  334. {
  335. if (Sse41.IsSupported)
  336. {
  337. if (Size == 0)
  338. {
  339. return Sse.StaticCast<byte, float>(Sse41.Insert(Sse.StaticCast<float, byte>(Vector), (byte)Value, Index));
  340. }
  341. else if (Size == 1)
  342. {
  343. return Sse.StaticCast<ushort, float>(Sse2.Insert(Sse.StaticCast<float, ushort>(Vector), (ushort)Value, Index));
  344. }
  345. else if (Size == 2)
  346. {
  347. return Sse.StaticCast<uint, float>(Sse41.Insert(Sse.StaticCast<float, uint>(Vector), (uint)Value, Index));
  348. }
  349. else if (Size == 3)
  350. {
  351. return Sse.StaticCast<ulong, float>(Sse41.Insert(Sse.StaticCast<float, ulong>(Vector), Value, Index));
  352. }
  353. else
  354. {
  355. throw new ArgumentOutOfRangeException(nameof(Size));
  356. }
  357. }
  358. else if (Sse2.IsSupported)
  359. {
  360. Vector128<ushort> ShortVector = Sse.StaticCast<float, ushort>(Vector);
  361. int ShortIdx = Size == 0
  362. ? Index >> 1
  363. : Index << (Size - 1);
  364. if (Size == 0)
  365. {
  366. ushort ShortVal = Sse2.Extract(Sse.StaticCast<float, ushort>(Vector), (byte)ShortIdx);
  367. int Shift = (Index & 1) * 8;
  368. ShortVal &= (ushort)(0xff00 >> Shift);
  369. ShortVal |= (ushort)((byte)Value << Shift);
  370. return Sse.StaticCast<ushort, float>(Sse2.Insert(ShortVector, ShortVal, (byte)ShortIdx));
  371. }
  372. else if (Size == 1)
  373. {
  374. return Sse.StaticCast<ushort, float>(Sse2.Insert(Sse.StaticCast<float, ushort>(Vector), (ushort)Value, Index));
  375. }
  376. else if (Size == 2 || Size == 3)
  377. {
  378. ShortVector = Sse2.Insert(ShortVector, (ushort)(Value >> 0), (byte)(ShortIdx + 0));
  379. ShortVector = Sse2.Insert(ShortVector, (ushort)(Value >> 16), (byte)(ShortIdx + 1));
  380. if (Size == 3)
  381. {
  382. ShortVector = Sse2.Insert(ShortVector, (ushort)(Value >> 32), (byte)(ShortIdx + 2));
  383. ShortVector = Sse2.Insert(ShortVector, (ushort)(Value >> 48), (byte)(ShortIdx + 3));
  384. }
  385. return Sse.StaticCast<ushort, float>(ShortVector);
  386. }
  387. else
  388. {
  389. throw new ArgumentOutOfRangeException(nameof(Size));
  390. }
  391. }
  392. throw new PlatformNotSupportedException();
  393. }
  394. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  395. public static Vector128<float> VectorInsertSingle(float Value, Vector128<float> Vector, byte Index)
  396. {
  397. if (Sse41.IsSupported)
  398. {
  399. //Note: The if/else if is necessary to enable the JIT to
  400. //produce a single INSERTPS instruction instead of the
  401. //jump table fallback.
  402. if (Index == 0)
  403. {
  404. return Sse41.Insert(Vector, Value, 0x00);
  405. }
  406. else if (Index == 1)
  407. {
  408. return Sse41.Insert(Vector, Value, 0x10);
  409. }
  410. else if (Index == 2)
  411. {
  412. return Sse41.Insert(Vector, Value, 0x20);
  413. }
  414. else if (Index == 3)
  415. {
  416. return Sse41.Insert(Vector, Value, 0x30);
  417. }
  418. else
  419. {
  420. throw new ArgumentOutOfRangeException(nameof(Index));
  421. }
  422. }
  423. else if (Sse2.IsSupported)
  424. {
  425. int IntValue = BitConverter.SingleToInt32Bits(Value);
  426. ushort Low = (ushort)(IntValue >> 0);
  427. ushort High = (ushort)(IntValue >> 16);
  428. Vector128<ushort> ShortVector = Sse.StaticCast<float, ushort>(Vector);
  429. ShortVector = Sse2.Insert(ShortVector, Low, (byte)(Index * 2 + 0));
  430. ShortVector = Sse2.Insert(ShortVector, High, (byte)(Index * 2 + 1));
  431. return Sse.StaticCast<ushort, float>(ShortVector);
  432. }
  433. throw new PlatformNotSupportedException();
  434. }
  435. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  436. public static Vector128<float> Sse41VectorInsertScalarSingle(float Value, Vector128<float> Vector)
  437. {
  438. //Note: 0b1110 is the mask to zero the upper bits.
  439. return Sse41.Insert(Vector, Value, 0b1110);
  440. }
  441. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  442. public static Vector128<sbyte> VectorSByteZero()
  443. {
  444. if (Sse2.IsSupported)
  445. {
  446. return Sse2.SetZeroVector128<sbyte>();
  447. }
  448. throw new PlatformNotSupportedException();
  449. }
  450. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  451. public static Vector128<short> VectorInt16Zero()
  452. {
  453. if (Sse2.IsSupported)
  454. {
  455. return Sse2.SetZeroVector128<short>();
  456. }
  457. throw new PlatformNotSupportedException();
  458. }
  459. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  460. public static Vector128<int> VectorInt32Zero()
  461. {
  462. if (Sse2.IsSupported)
  463. {
  464. return Sse2.SetZeroVector128<int>();
  465. }
  466. throw new PlatformNotSupportedException();
  467. }
  468. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  469. public static Vector128<long> VectorInt64Zero()
  470. {
  471. if (Sse2.IsSupported)
  472. {
  473. return Sse2.SetZeroVector128<long>();
  474. }
  475. throw new PlatformNotSupportedException();
  476. }
  477. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  478. public static Vector128<float> VectorSingleZero()
  479. {
  480. if (Sse.IsSupported)
  481. {
  482. return Sse.SetZeroVector128();
  483. }
  484. throw new PlatformNotSupportedException();
  485. }
  486. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  487. public static Vector128<double> VectorDoubleZero()
  488. {
  489. if (Sse2.IsSupported)
  490. {
  491. return Sse2.SetZeroVector128<double>();
  492. }
  493. throw new PlatformNotSupportedException();
  494. }
  495. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  496. public static Vector128<float> VectorZero32_128(Vector128<float> Vector)
  497. {
  498. if (Sse.IsSupported)
  499. {
  500. return Sse.And(Vector, Zero32_128Mask);
  501. }
  502. throw new PlatformNotSupportedException();
  503. }
  504. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  505. public static Vector128<sbyte> VectorSingleToSByte(Vector128<float> Vector)
  506. {
  507. if (Sse.IsSupported)
  508. {
  509. return Sse.StaticCast<float, sbyte>(Vector);
  510. }
  511. throw new PlatformNotSupportedException();
  512. }
  513. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  514. public static Vector128<short> VectorSingleToInt16(Vector128<float> Vector)
  515. {
  516. if (Sse.IsSupported)
  517. {
  518. return Sse.StaticCast<float, short>(Vector);
  519. }
  520. throw new PlatformNotSupportedException();
  521. }
  522. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  523. public static Vector128<int> VectorSingleToInt32(Vector128<float> Vector)
  524. {
  525. if (Sse.IsSupported)
  526. {
  527. return Sse.StaticCast<float, int>(Vector);
  528. }
  529. throw new PlatformNotSupportedException();
  530. }
  531. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  532. public static Vector128<long> VectorSingleToInt64(Vector128<float> Vector)
  533. {
  534. if (Sse.IsSupported)
  535. {
  536. return Sse.StaticCast<float, long>(Vector);
  537. }
  538. throw new PlatformNotSupportedException();
  539. }
  540. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  541. public static Vector128<byte> VectorSingleToByte(Vector128<float> Vector)
  542. {
  543. if (Sse.IsSupported)
  544. {
  545. return Sse.StaticCast<float, byte>(Vector);
  546. }
  547. throw new PlatformNotSupportedException();
  548. }
  549. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  550. public static Vector128<ushort> VectorSingleToUInt16(Vector128<float> Vector)
  551. {
  552. if (Sse.IsSupported)
  553. {
  554. return Sse.StaticCast<float, ushort>(Vector);
  555. }
  556. throw new PlatformNotSupportedException();
  557. }
  558. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  559. public static Vector128<uint> VectorSingleToUInt32(Vector128<float> Vector)
  560. {
  561. if (Sse.IsSupported)
  562. {
  563. return Sse.StaticCast<float, uint>(Vector);
  564. }
  565. throw new PlatformNotSupportedException();
  566. }
  567. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  568. public static Vector128<ulong> VectorSingleToUInt64(Vector128<float> Vector)
  569. {
  570. if (Sse.IsSupported)
  571. {
  572. return Sse.StaticCast<float, ulong>(Vector);
  573. }
  574. throw new PlatformNotSupportedException();
  575. }
  576. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  577. public static Vector128<double> VectorSingleToDouble(Vector128<float> Vector)
  578. {
  579. if (Sse.IsSupported)
  580. {
  581. return Sse.StaticCast<float, double>(Vector);
  582. }
  583. throw new PlatformNotSupportedException();
  584. }
  585. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  586. public static Vector128<float> VectorSByteToSingle(Vector128<sbyte> Vector)
  587. {
  588. if (Sse.IsSupported)
  589. {
  590. return Sse.StaticCast<sbyte, float>(Vector);
  591. }
  592. throw new PlatformNotSupportedException();
  593. }
  594. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  595. public static Vector128<float> VectorInt16ToSingle(Vector128<short> Vector)
  596. {
  597. if (Sse.IsSupported)
  598. {
  599. return Sse.StaticCast<short, float>(Vector);
  600. }
  601. throw new PlatformNotSupportedException();
  602. }
  603. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  604. public static Vector128<float> VectorInt32ToSingle(Vector128<int> Vector)
  605. {
  606. if (Sse.IsSupported)
  607. {
  608. return Sse.StaticCast<int, float>(Vector);
  609. }
  610. throw new PlatformNotSupportedException();
  611. }
  612. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  613. public static Vector128<float> VectorInt64ToSingle(Vector128<long> Vector)
  614. {
  615. if (Sse.IsSupported)
  616. {
  617. return Sse.StaticCast<long, float>(Vector);
  618. }
  619. throw new PlatformNotSupportedException();
  620. }
  621. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  622. public static Vector128<float> VectorByteToSingle(Vector128<byte> Vector)
  623. {
  624. if (Sse.IsSupported)
  625. {
  626. return Sse.StaticCast<byte, float>(Vector);
  627. }
  628. throw new PlatformNotSupportedException();
  629. }
  630. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  631. public static Vector128<float> VectorUInt16ToSingle(Vector128<ushort> Vector)
  632. {
  633. if (Sse.IsSupported)
  634. {
  635. return Sse.StaticCast<ushort, float>(Vector);
  636. }
  637. throw new PlatformNotSupportedException();
  638. }
  639. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  640. public static Vector128<float> VectorUInt32ToSingle(Vector128<uint> Vector)
  641. {
  642. if (Sse.IsSupported)
  643. {
  644. return Sse.StaticCast<uint, float>(Vector);
  645. }
  646. throw new PlatformNotSupportedException();
  647. }
  648. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  649. public static Vector128<float> VectorUInt64ToSingle(Vector128<ulong> Vector)
  650. {
  651. if (Sse.IsSupported)
  652. {
  653. return Sse.StaticCast<ulong, float>(Vector);
  654. }
  655. throw new PlatformNotSupportedException();
  656. }
  657. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  658. public static Vector128<float> VectorDoubleToSingle(Vector128<double> Vector)
  659. {
  660. if (Sse.IsSupported)
  661. {
  662. return Sse.StaticCast<double, float>(Vector);
  663. }
  664. throw new PlatformNotSupportedException();
  665. }
  666. }
  667. }