CpuTestSimdRegElem.cs 4.0 KB

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