CpuTestAlu32.cs
1 #define Alu32 2 3 using NUnit.Framework; 4 5 namespace Ryujinx.Tests.Cpu 6 { 7 [Category("Alu32")] 8 public sealed class CpuTestAlu32 : CpuTest32 9 { 10 #if Alu32 11 12 #region "ValueSource (Opcodes)" 13 private static uint[] SuHAddSub8() 14 { 15 return new[] 16 { 17 0xe6100f90u, // SADD8 R0, R0, R0 18 0xe6100ff0u, // SSUB8 R0, R0, R0 19 0xe6300f90u, // SHADD8 R0, R0, R0 20 0xe6300ff0u, // SHSUB8 R0, R0, R0 21 0xe6500f90u, // UADD8 R0, R0, R0 22 0xe6500ff0u, // USUB8 R0, R0, R0 23 0xe6700f90u, // UHADD8 R0, R0, R0 24 0xe6700ff0u, // UHSUB8 R0, R0, R0 25 }; 26 } 27 28 private static uint[] UQAddSub16() 29 { 30 return new[] 31 { 32 0xe6200f10u, // QADD16 R0, R0, R0 33 0xe6600f10u, // UQADD16 R0, R0, R0 34 0xe6600f70u, // UQSUB16 R0, R0, R0 35 }; 36 } 37 38 private static uint[] UQAddSub8() 39 { 40 return new[] 41 { 42 0xe6600f90u, // UQADD8 R0, R0, R0 43 0xe6600ff0u, // UQSUB8 R0, R0, R0 44 }; 45 } 46 47 private static uint[] SsatUsat() 48 { 49 return new[] 50 { 51 0xe6a00010u, // SSAT R0, #1, R0, LSL #0 52 0xe6a00050u, // SSAT R0, #1, R0, ASR #32 53 0xe6e00010u, // USAT R0, #0, R0, LSL #0 54 0xe6e00050u, // USAT R0, #0, R0, ASR #32 55 }; 56 } 57 58 private static uint[] Ssat16Usat16() 59 { 60 return new[] 61 { 62 0xe6a00f30u, // SSAT16 R0, #1, R0 63 0xe6e00f30u, // USAT16 R0, #0, R0 64 }; 65 } 66 67 private static uint[] LsrLslAsrRor() 68 { 69 return new[] 70 { 71 0xe1b00030u, // LSRS R0, R0, R0 72 0xe1b00010u, // LSLS R0, R0, R0 73 0xe1b00050u, // ASRS R0, R0, R0 74 0xe1b00070u, // RORS R0, R0, R0 75 }; 76 } 77 #endregion 78 79 private const int RndCnt = 2; 80 81 [Test, Pairwise, Description("RBIT <Rd>, <Rn>")] 82 public void Rbit_32bit([Values(0u, 0xdu)] uint rd, 83 [Values(1u, 0xdu)] uint rm, 84 [Values(0x00000000u, 0x7FFFFFFFu, 85 0x80000000u, 0xFFFFFFFFu)] uint wn) 86 { 87 uint opcode = 0xe6ff0f30u; // RBIT R0, R0 88 opcode |= ((rm & 15) << 0) | ((rd & 15) << 12); 89 90 uint w31 = TestContext.CurrentContext.Random.NextUInt(); 91 92 SingleOpcode(opcode, r1: wn, sp: w31); 93 94 CompareAgainstUnicorn(); 95 } 96 97 [Test, Pairwise] 98 public void Lsr_Lsl_Asr_Ror([ValueSource(nameof(LsrLslAsrRor))] uint opcode, 99 [Values(0x00000000u, 0x7FFFFFFFu, 100 0x80000000u, 0xFFFFFFFFu)] uint shiftValue, 101 [Range(0, 31)] int shiftAmount) 102 { 103 uint rd = 0; 104 uint rm = 1; 105 uint rs = 2; 106 opcode |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rs & 15) << 8); 107 108 SingleOpcode(opcode, r1: shiftValue, r2: (uint)shiftAmount); 109 110 CompareAgainstUnicorn(); 111 } 112 113 [Test, Pairwise] 114 public void Shadd8([Values(0u, 0xdu)] uint rd, 115 [Values(1u)] uint rm, 116 [Values(2u)] uint rn, 117 [Random(RndCnt)] uint w0, 118 [Random(RndCnt)] uint w1, 119 [Random(RndCnt)] uint w2) 120 { 121 uint opcode = 0xE6300F90u; // SHADD8 R0, R0, R0 122 123 opcode |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16); 124 125 uint sp = TestContext.CurrentContext.Random.NextUInt(); 126 127 SingleOpcode(opcode, r0: w0, r1: w1, r2: w2, sp: sp); 128 129 CompareAgainstUnicorn(); 130 } 131 132 [Test, Pairwise] 133 public void Shsub8([Values(0u, 0xdu)] uint rd, 134 [Values(1u)] uint rm, 135 [Values(2u)] uint rn, 136 [Random(RndCnt)] uint w0, 137 [Random(RndCnt)] uint w1, 138 [Random(RndCnt)] uint w2) 139 { 140 uint opcode = 0xE6300FF0u; // SHSUB8 R0, R0, R0 141 142 opcode |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16); 143 144 uint sp = TestContext.CurrentContext.Random.NextUInt(); 145 146 SingleOpcode(opcode, r0: w0, r1: w1, r2: w2, sp: sp); 147 148 CompareAgainstUnicorn(); 149 } 150 151 [Test, Pairwise] 152 public void Ssat_Usat([ValueSource(nameof(SsatUsat))] uint opcode, 153 [Values(0u, 0xdu)] uint rd, 154 [Values(1u, 0xdu)] uint rn, 155 [Values(0u, 7u, 8u, 0xfu, 0x10u, 0x1fu)] uint sat, 156 [Values(0u, 7u, 8u, 0xfu, 0x10u, 0x1fu)] uint shift, 157 [Values(0x00000000u, 0x7FFFFFFFu, 158 0x80000000u, 0xFFFFFFFFu)] uint wn) 159 { 160 opcode |= ((rn & 15) << 0) | ((shift & 31) << 7) | ((rd & 15) << 12) | ((sat & 31) << 16); 161 162 uint w31 = TestContext.CurrentContext.Random.NextUInt(); 163 164 SingleOpcode(opcode, r1: wn, sp: w31); 165 166 CompareAgainstUnicorn(); 167 } 168 169 [Test, Pairwise] 170 public void Ssat16_Usat16([ValueSource(nameof(Ssat16Usat16))] uint opcode, 171 [Values(0u, 0xdu)] uint rd, 172 [Values(1u, 0xdu)] uint rn, 173 [Values(0u, 7u, 8u, 0xfu)] uint sat, 174 [Values(0x00000000u, 0x7FFFFFFFu, 175 0x80000000u, 0xFFFFFFFFu)] uint wn) 176 { 177 opcode |= ((rn & 15) << 0) | ((rd & 15) << 12) | ((sat & 15) << 16); 178 179 uint w31 = TestContext.CurrentContext.Random.NextUInt(); 180 181 SingleOpcode(opcode, r1: wn, sp: w31); 182 183 CompareAgainstUnicorn(); 184 } 185 186 [Test, Pairwise] 187 public void SU_H_AddSub_8([ValueSource(nameof(SuHAddSub8))] uint opcode, 188 [Values(0u, 0xdu)] uint rd, 189 [Values(1u)] uint rm, 190 [Values(2u)] uint rn, 191 [Random(RndCnt)] uint w0, 192 [Random(RndCnt)] uint w1, 193 [Random(RndCnt)] uint w2) 194 { 195 opcode |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16); 196 197 uint sp = TestContext.CurrentContext.Random.NextUInt(); 198 199 SingleOpcode(opcode, r0: w0, r1: w1, r2: w2, sp: sp); 200 201 CompareAgainstUnicorn(); 202 } 203 204 [Test, Pairwise] 205 public void U_Q_AddSub_16([ValueSource(nameof(UQAddSub16))] uint opcode, 206 [Values(0u, 0xdu)] uint rd, 207 [Values(1u)] uint rm, 208 [Values(2u)] uint rn, 209 [Random(RndCnt)] uint w0, 210 [Random(RndCnt)] uint w1, 211 [Random(RndCnt)] uint w2) 212 { 213 opcode |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16); 214 215 uint sp = TestContext.CurrentContext.Random.NextUInt(); 216 217 SingleOpcode(opcode, r0: w0, r1: w1, r2: w2, sp: sp); 218 219 CompareAgainstUnicorn(); 220 } 221 222 [Test, Pairwise] 223 public void U_Q_AddSub_8([ValueSource(nameof(UQAddSub8))] uint opcode, 224 [Values(0u, 0xdu)] uint rd, 225 [Values(1u)] uint rm, 226 [Values(2u)] uint rn, 227 [Random(RndCnt)] uint w0, 228 [Random(RndCnt)] uint w1, 229 [Random(RndCnt)] uint w2) 230 { 231 opcode |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16); 232 233 uint sp = TestContext.CurrentContext.Random.NextUInt(); 234 235 SingleOpcode(opcode, r0: w0, r1: w1, r2: w2, sp: sp); 236 237 CompareAgainstUnicorn(); 238 } 239 240 [Test, Pairwise] 241 public void Uadd8_Sel([Values(0u)] uint rd, 242 [Values(1u)] uint rm, 243 [Values(2u)] uint rn, 244 [Random(RndCnt)] uint w0, 245 [Random(RndCnt)] uint w1, 246 [Random(RndCnt)] uint w2) 247 { 248 uint opUadd8 = 0xE6500F90; // UADD8 R0, R0, R0 249 uint opSel = 0xE6800FB0; // SEL R0, R0, R0 250 251 opUadd8 |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16); 252 opSel |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16); 253 254 SetContext(r0: w0, r1: w1, r2: w2); 255 Opcode(opUadd8); 256 Opcode(opSel); 257 Opcode(0xE12FFF1E); // BX LR 258 ExecuteOpcodes(); 259 260 CompareAgainstUnicorn(); 261 } 262 #endif 263 } 264 }