/ src / Ryujinx.Tests / Cpu / CpuTestSimdFcond.cs
CpuTestSimdFcond.cs
  1  #define SimdFcond
  2  
  3  using ARMeilleure.State;
  4  using NUnit.Framework;
  5  using System.Collections.Generic;
  6  
  7  namespace Ryujinx.Tests.Cpu
  8  {
  9      [Category("SimdFcond")]
 10      public sealed class CpuTestSimdFcond : CpuTest
 11      {
 12  #if SimdFcond
 13  
 14          #region "ValueSource (Types)"
 15          private static IEnumerable<ulong> _1S_F_()
 16          {
 17              yield return 0x00000000FF7FFFFFul; // -Max Normal    (float.MinValue)
 18              yield return 0x0000000080800000ul; // -Min Normal
 19              yield return 0x00000000807FFFFFul; // -Max Subnormal
 20              yield return 0x0000000080000001ul; // -Min Subnormal (-float.Epsilon)
 21              yield return 0x000000007F7FFFFFul; // +Max Normal    (float.MaxValue)
 22              yield return 0x0000000000800000ul; // +Min Normal
 23              yield return 0x00000000007FFFFFul; // +Max Subnormal
 24              yield return 0x0000000000000001ul; // +Min Subnormal (float.Epsilon)
 25  
 26              if (!_noZeros)
 27              {
 28                  yield return 0x0000000080000000ul; // -Zero
 29                  yield return 0x0000000000000000ul; // +Zero
 30              }
 31  
 32              if (!_noInfs)
 33              {
 34                  yield return 0x00000000FF800000ul; // -Infinity
 35                  yield return 0x000000007F800000ul; // +Infinity
 36              }
 37  
 38              if (!_noNaNs)
 39              {
 40                  yield return 0x00000000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
 41                  yield return 0x00000000FFBFFFFFul; // -SNaN (all ones  payload)
 42                  yield return 0x000000007FC00000ul; // +QNaN (all zeros payload) (-float.NaN) (DefaultNaN)
 43                  yield return 0x000000007FBFFFFFul; // +SNaN (all ones  payload)
 44              }
 45  
 46              for (int cnt = 1; cnt <= RndCnt; cnt++)
 47              {
 48                  ulong grbg = TestContext.CurrentContext.Random.NextUInt();
 49                  ulong rnd1 = GenNormalS();
 50                  ulong rnd2 = GenSubnormalS();
 51  
 52                  yield return (grbg << 32) | rnd1;
 53                  yield return (grbg << 32) | rnd2;
 54              }
 55          }
 56  
 57          private static IEnumerable<ulong> _1D_F_()
 58          {
 59              yield return 0xFFEFFFFFFFFFFFFFul; // -Max Normal    (double.MinValue)
 60              yield return 0x8010000000000000ul; // -Min Normal
 61              yield return 0x800FFFFFFFFFFFFFul; // -Max Subnormal
 62              yield return 0x8000000000000001ul; // -Min Subnormal (-double.Epsilon)
 63              yield return 0x7FEFFFFFFFFFFFFFul; // +Max Normal    (double.MaxValue)
 64              yield return 0x0010000000000000ul; // +Min Normal
 65              yield return 0x000FFFFFFFFFFFFFul; // +Max Subnormal
 66              yield return 0x0000000000000001ul; // +Min Subnormal (double.Epsilon)
 67  
 68              if (!_noZeros)
 69              {
 70                  yield return 0x8000000000000000ul; // -Zero
 71                  yield return 0x0000000000000000ul; // +Zero
 72              }
 73  
 74              if (!_noInfs)
 75              {
 76                  yield return 0xFFF0000000000000ul; // -Infinity
 77                  yield return 0x7FF0000000000000ul; // +Infinity
 78              }
 79  
 80              if (!_noNaNs)
 81              {
 82                  yield return 0xFFF8000000000000ul; // -QNaN (all zeros payload) (double.NaN)
 83                  yield return 0xFFF7FFFFFFFFFFFFul; // -SNaN (all ones  payload)
 84                  yield return 0x7FF8000000000000ul; // +QNaN (all zeros payload) (-double.NaN) (DefaultNaN)
 85                  yield return 0x7FF7FFFFFFFFFFFFul; // +SNaN (all ones  payload)
 86              }
 87  
 88              for (int cnt = 1; cnt <= RndCnt; cnt++)
 89              {
 90                  ulong rnd1 = GenNormalD();
 91                  ulong rnd2 = GenSubnormalD();
 92  
 93                  yield return rnd1;
 94                  yield return rnd2;
 95              }
 96          }
 97          #endregion
 98  
 99          #region "ValueSource (Opcodes)"
100          private static uint[] _F_Ccmp_Ccmpe_S_S_()
101          {
102              return new[]
103              {
104                  0x1E220420u, // FCCMP  S1, S2, #0, EQ
105                  0x1E220430u, // FCCMPE S1, S2, #0, EQ
106              };
107          }
108  
109          private static uint[] _F_Ccmp_Ccmpe_S_D_()
110          {
111              return new[]
112              {
113                  0x1E620420u, // FCCMP  D1, D2, #0, EQ
114                  0x1E620430u, // FCCMPE D1, D2, #0, EQ
115              };
116          }
117  
118          private static uint[] _F_Csel_S_S_()
119          {
120              return new[]
121              {
122                  0x1E220C20u, // FCSEL S0, S1, S2, EQ
123              };
124          }
125  
126          private static uint[] _F_Csel_S_D_()
127          {
128              return new[]
129              {
130                  0x1E620C20u, // FCSEL D0, D1, D2, EQ
131              };
132          }
133          #endregion
134  
135          private const int RndCnt = 2;
136          private const int RndCntNzcv = 2;
137  
138          private static readonly bool _noZeros = false;
139          private static readonly bool _noInfs = false;
140          private static readonly bool _noNaNs = false;
141  
142          [Test, Pairwise]
143          [Explicit]
144          public void F_Ccmp_Ccmpe_S_S([ValueSource(nameof(_F_Ccmp_Ccmpe_S_S_))] uint opcodes,
145                                       [ValueSource(nameof(_1S_F_))] ulong a,
146                                       [ValueSource(nameof(_1S_F_))] ulong b,
147                                       [Random(0u, 15u, RndCntNzcv)] uint nzcv,
148                                       [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u,             // <EQ, NE, CS/HS, CC/LO,
149                                               0b0100u, 0b0101u, 0b0110u, 0b0111u,             //  MI, PL, VS, VC,
150                                               0b1000u, 0b1001u, 0b1010u, 0b1011u,             //  HI, LS, GE, LT,
151                                               0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) //  GT, LE, AL, NV>
152          {
153              opcodes |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
154  
155              V128 v1 = MakeVectorE0(a);
156              V128 v2 = MakeVectorE0(b);
157  
158              bool v = TestContext.CurrentContext.Random.NextBool();
159              bool c = TestContext.CurrentContext.Random.NextBool();
160              bool z = TestContext.CurrentContext.Random.NextBool();
161              bool n = TestContext.CurrentContext.Random.NextBool();
162  
163              SingleOpcode(opcodes, v1: v1, v2: v2, overflow: v, carry: c, zero: z, negative: n);
164  
165              CompareAgainstUnicorn(fpsrMask: Fpsr.Ioc);
166          }
167  
168          [Test, Pairwise]
169          [Explicit]
170          public void F_Ccmp_Ccmpe_S_D([ValueSource(nameof(_F_Ccmp_Ccmpe_S_D_))] uint opcodes,
171                                       [ValueSource(nameof(_1D_F_))] ulong a,
172                                       [ValueSource(nameof(_1D_F_))] ulong b,
173                                       [Random(0u, 15u, RndCntNzcv)] uint nzcv,
174                                       [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u,             // <EQ, NE, CS/HS, CC/LO,
175                                               0b0100u, 0b0101u, 0b0110u, 0b0111u,             //  MI, PL, VS, VC,
176                                               0b1000u, 0b1001u, 0b1010u, 0b1011u,             //  HI, LS, GE, LT,
177                                               0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) //  GT, LE, AL, NV>
178          {
179              opcodes |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
180  
181              V128 v1 = MakeVectorE0(a);
182              V128 v2 = MakeVectorE0(b);
183  
184              bool v = TestContext.CurrentContext.Random.NextBool();
185              bool c = TestContext.CurrentContext.Random.NextBool();
186              bool z = TestContext.CurrentContext.Random.NextBool();
187              bool n = TestContext.CurrentContext.Random.NextBool();
188  
189              SingleOpcode(opcodes, v1: v1, v2: v2, overflow: v, carry: c, zero: z, negative: n);
190  
191              CompareAgainstUnicorn(fpsrMask: Fpsr.Ioc);
192          }
193  
194          [Test, Pairwise]
195          [Explicit]
196          public void F_Csel_S_S([ValueSource(nameof(_F_Csel_S_S_))] uint opcodes,
197                                 [ValueSource(nameof(_1S_F_))] ulong a,
198                                 [ValueSource(nameof(_1S_F_))] ulong b,
199                                 [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u,             // <EQ, NE, CS/HS, CC/LO,
200                                         0b0100u, 0b0101u, 0b0110u, 0b0111u,             //  MI, PL, VS, VC,
201                                         0b1000u, 0b1001u, 0b1010u, 0b1011u,             //  HI, LS, GE, LT,
202                                         0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) //  GT, LE, AL, NV>
203          {
204              opcodes |= ((cond & 15) << 12);
205  
206              ulong z = TestContext.CurrentContext.Random.NextULong();
207              V128 v0 = MakeVectorE0E1(z, z);
208              V128 v1 = MakeVectorE0(a);
209              V128 v2 = MakeVectorE0(b);
210  
211              SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
212  
213              CompareAgainstUnicorn();
214          }
215  
216          [Test, Pairwise]
217          [Explicit]
218          public void F_Csel_S_D([ValueSource(nameof(_F_Csel_S_D_))] uint opcodes,
219                                 [ValueSource(nameof(_1D_F_))] ulong a,
220                                 [ValueSource(nameof(_1D_F_))] ulong b,
221                                 [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u,             // <EQ, NE, CS/HS, CC/LO,
222                                         0b0100u, 0b0101u, 0b0110u, 0b0111u,             //  MI, PL, VS, VC,
223                                         0b1000u, 0b1001u, 0b1010u, 0b1011u,             //  HI, LS, GE, LT,
224                                         0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) //  GT, LE, AL, NV>
225          {
226              opcodes |= ((cond & 15) << 12);
227  
228              ulong z = TestContext.CurrentContext.Random.NextULong();
229              V128 v0 = MakeVectorE1(z);
230              V128 v1 = MakeVectorE0(a);
231              V128 v2 = MakeVectorE0(b);
232  
233              SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
234  
235              CompareAgainstUnicorn();
236          }
237  #endif
238      }
239  }