CpuTestSimdCrypto.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // https://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf
  2. using ChocolArm64.State;
  3. using NUnit.Framework;
  4. using System.Runtime.Intrinsics;
  5. namespace Ryujinx.Tests.Cpu
  6. {
  7. public class CpuTestSimdCrypto : CpuTest
  8. {
  9. [Test, Explicit, Description("AESD <Vd>.16B, <Vn>.16B")]
  10. public void Aesd_V([Values(0u)] uint Rd,
  11. [Values(1u)] uint Rn,
  12. [Values(0x7B5B546573745665ul)] ulong ValueH,
  13. [Values(0x63746F725D53475Dul)] ulong ValueL,
  14. [Random(2)] ulong RoundKeyH,
  15. [Random(2)] ulong RoundKeyL,
  16. [Values(0x8DCAB9BC035006BCul)] ulong ResultH,
  17. [Values(0x8F57161E00CAFD8Dul)] ulong ResultL)
  18. {
  19. uint Opcode = 0x4E285800; // AESD V0.16B, V0.16B
  20. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  21. Vector128<float> V0 = MakeVectorE0E1(RoundKeyL ^ ValueL, RoundKeyH ^ ValueH);
  22. Vector128<float> V1 = MakeVectorE0E1(RoundKeyL, RoundKeyH);
  23. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  24. Assert.Multiple(() =>
  25. {
  26. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(ResultL));
  27. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(ResultH));
  28. });
  29. Assert.Multiple(() =>
  30. {
  31. Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(RoundKeyL));
  32. Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(RoundKeyH));
  33. });
  34. }
  35. [Test, Explicit, Description("AESE <Vd>.16B, <Vn>.16B")]
  36. public void Aese_V([Values(0u)] uint Rd,
  37. [Values(1u)] uint Rn,
  38. [Values(0x7B5B546573745665ul)] ulong ValueH,
  39. [Values(0x63746F725D53475Dul)] ulong ValueL,
  40. [Random(2)] ulong RoundKeyH,
  41. [Random(2)] ulong RoundKeyL,
  42. [Values(0x8F92A04DFBED204Dul)] ulong ResultH,
  43. [Values(0x4C39B1402192A84Cul)] ulong ResultL)
  44. {
  45. uint Opcode = 0x4E284800; // AESE V0.16B, V0.16B
  46. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  47. Vector128<float> V0 = MakeVectorE0E1(RoundKeyL ^ ValueL, RoundKeyH ^ ValueH);
  48. Vector128<float> V1 = MakeVectorE0E1(RoundKeyL, RoundKeyH);
  49. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  50. Assert.Multiple(() =>
  51. {
  52. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(ResultL));
  53. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(ResultH));
  54. });
  55. Assert.Multiple(() =>
  56. {
  57. Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(RoundKeyL));
  58. Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(RoundKeyH));
  59. });
  60. }
  61. [Test, Explicit, Description("AESIMC <Vd>.16B, <Vn>.16B")]
  62. public void Aesimc_V([Values(0u)] uint Rd,
  63. [Values(1u, 0u)] uint Rn,
  64. [Values(0x8DCAB9DC035006BCul)] ulong ValueH,
  65. [Values(0x8F57161E00CAFD8Dul)] ulong ValueL,
  66. [Values(0xD635A667928B5EAEul)] ulong ResultH,
  67. [Values(0xEEC9CC3BC55F5777ul)] ulong ResultL)
  68. {
  69. uint Opcode = 0x4E287800; // AESIMC V0.16B, V0.16B
  70. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  71. Vector128<float> V = MakeVectorE0E1(ValueL, ValueH);
  72. AThreadState ThreadState = SingleOpcode(
  73. Opcode,
  74. V0: Rn == 0u ? V : default(Vector128<float>),
  75. V1: Rn == 1u ? V : default(Vector128<float>));
  76. Assert.Multiple(() =>
  77. {
  78. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(ResultL));
  79. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(ResultH));
  80. });
  81. if (Rn == 1u)
  82. {
  83. Assert.Multiple(() =>
  84. {
  85. Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(ValueL));
  86. Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(ValueH));
  87. });
  88. }
  89. }
  90. [Test, Explicit, Description("AESMC <Vd>.16B, <Vn>.16B")]
  91. public void Aesmc_V([Values(0u)] uint Rd,
  92. [Values(1u, 0u)] uint Rn,
  93. [Values(0x627A6F6644B109C8ul)] ulong ValueH,
  94. [Values(0x2B18330A81C3B3E5ul)] ulong ValueL,
  95. [Values(0x7B5B546573745665ul)] ulong ResultH,
  96. [Values(0x63746F725D53475Dul)] ulong ResultL)
  97. {
  98. uint Opcode = 0x4E286800; // AESMC V0.16B, V0.16B
  99. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  100. Vector128<float> V = MakeVectorE0E1(ValueL, ValueH);
  101. AThreadState ThreadState = SingleOpcode(
  102. Opcode,
  103. V0: Rn == 0u ? V : default(Vector128<float>),
  104. V1: Rn == 1u ? V : default(Vector128<float>));
  105. Assert.Multiple(() =>
  106. {
  107. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(ResultL));
  108. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(ResultH));
  109. });
  110. if (Rn == 1u)
  111. {
  112. Assert.Multiple(() =>
  113. {
  114. Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(ValueL));
  115. Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(ValueH));
  116. });
  117. }
  118. }
  119. }
  120. }