CpuTestSimdRegElem.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #define SimdRegElem
  2. using NUnit.Framework;
  3. using System.Runtime.Intrinsics;
  4. namespace Ryujinx.Tests.Cpu
  5. {
  6. [Category("SimdRegElem")]
  7. public sealed class CpuTestSimdRegElem : CpuTest
  8. {
  9. #if SimdRegElem
  10. #region "ValueSource (Types)"
  11. private static ulong[] _2S_()
  12. {
  13. return new ulong[] { 0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul,
  14. 0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
  15. }
  16. private static ulong[] _4H_()
  17. {
  18. return new ulong[] { 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
  19. 0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul };
  20. }
  21. #endregion
  22. #region "ValueSource (Opcodes)"
  23. private static uint[] _Mla_Mls_Mul_Ve_4H_8H_()
  24. {
  25. return new uint[]
  26. {
  27. 0x2F400000u, // MLA V0.4H, V0.4H, V0.H[0]
  28. 0x2F404000u, // MLS V0.4H, V0.4H, V0.H[0]
  29. 0x0F408000u // MUL V0.4H, V0.4H, V0.H[0]
  30. };
  31. }
  32. private static uint[] _Mla_Mls_Mul_Ve_2S_4S_()
  33. {
  34. return new uint[]
  35. {
  36. 0x2F800000u, // MLA V0.2S, V0.2S, V0.S[0]
  37. 0x2F804000u, // MLS V0.2S, V0.2S, V0.S[0]
  38. 0x0F808000u // MUL V0.2S, V0.2S, V0.S[0]
  39. };
  40. }
  41. #endregion
  42. private const int RndCnt = 2;
  43. [Test, Pairwise]
  44. public void Mla_Mls_Mul_Ve_4H_8H([ValueSource("_Mla_Mls_Mul_Ve_4H_8H_")] uint opcodes,
  45. [Values(0u)] uint rd,
  46. [Values(1u, 0u)] uint rn,
  47. [Values(2u, 0u)] uint rm,
  48. [ValueSource("_4H_")] [Random(RndCnt)] ulong z,
  49. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  50. [ValueSource("_4H_")] [Random(RndCnt)] ulong b,
  51. [Values(0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u)] uint index,
  52. [Values(0b0u, 0b1u)] uint q) // <4H, 8H>
  53. {
  54. uint h = (index >> 2) & 1;
  55. uint l = (index >> 1) & 1;
  56. uint m = index & 1;
  57. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  58. opcodes |= (l << 21) | (m << 20) | (h << 11);
  59. opcodes |= ((q & 1) << 30);
  60. Vector128<float> v0 = MakeVectorE0E1(z, z);
  61. Vector128<float> v1 = MakeVectorE0E1(a, a * q);
  62. Vector128<float> v2 = MakeVectorE0E1(b, b * h);
  63. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  64. CompareAgainstUnicorn();
  65. }
  66. [Test, Pairwise]
  67. public void Mla_Mls_Mul_Ve_2S_4S([ValueSource("_Mla_Mls_Mul_Ve_2S_4S_")] uint opcodes,
  68. [Values(0u)] uint rd,
  69. [Values(1u, 0u)] uint rn,
  70. [Values(2u, 0u)] uint rm,
  71. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  72. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  73. [ValueSource("_2S_")] [Random(RndCnt)] ulong b,
  74. [Values(0u, 1u, 2u, 3u)] uint index,
  75. [Values(0b0u, 0b1u)] uint q) // <2S, 4S>
  76. {
  77. uint h = (index >> 1) & 1;
  78. uint l = index & 1;
  79. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  80. opcodes |= (l << 21) | (h << 11);
  81. opcodes |= ((q & 1) << 30);
  82. Vector128<float> v0 = MakeVectorE0E1(z, z);
  83. Vector128<float> v1 = MakeVectorE0E1(a, a * q);
  84. Vector128<float> v2 = MakeVectorE0E1(b, b * h);
  85. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  86. CompareAgainstUnicorn();
  87. }
  88. #endif
  89. }
  90. }