CpuTestSimdShImm.cs 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058
  1. #define SimdShImm
  2. using ARMeilleure.State;
  3. using NUnit.Framework;
  4. using System;
  5. using System.Collections.Generic;
  6. namespace Ryujinx.Tests.Cpu
  7. {
  8. [Category("SimdShImm")]
  9. public sealed class CpuTestSimdShImm : CpuTest
  10. {
  11. #if SimdShImm
  12. #region "ValueSource (Types)"
  13. private static ulong[] _1D_()
  14. {
  15. return new ulong[] { 0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  16. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
  17. }
  18. private static ulong[] _1H_()
  19. {
  20. return new ulong[] { 0x0000000000000000ul, 0x0000000000007FFFul,
  21. 0x0000000000008000ul, 0x000000000000FFFFul };
  22. }
  23. private static ulong[] _1S_()
  24. {
  25. return new ulong[] { 0x0000000000000000ul, 0x000000007FFFFFFFul,
  26. 0x0000000080000000ul, 0x00000000FFFFFFFFul };
  27. }
  28. private static ulong[] _2S_()
  29. {
  30. return new ulong[] { 0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul,
  31. 0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
  32. }
  33. private static ulong[] _4H_()
  34. {
  35. return new ulong[] { 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
  36. 0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul };
  37. }
  38. private static ulong[] _8B_()
  39. {
  40. return new ulong[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
  41. 0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul };
  42. }
  43. private static IEnumerable<ulong> _2S_F_W_()
  44. {
  45. // int
  46. yield return 0xCF000001CF000001ul; // -2.1474839E9f (-2147483904)
  47. yield return 0xCF000000CF000000ul; // -2.14748365E9f (-2147483648)
  48. yield return 0xCEFFFFFFCEFFFFFFul; // -2.14748352E9f (-2147483520)
  49. yield return 0x4F0000014F000001ul; // 2.1474839E9f (2147483904)
  50. yield return 0x4F0000004F000000ul; // 2.14748365E9f (2147483648)
  51. yield return 0x4EFFFFFF4EFFFFFFul; // 2.14748352E9f (2147483520)
  52. // uint
  53. yield return 0x4F8000014F800001ul; // 4.2949678E9f (4294967808)
  54. yield return 0x4F8000004F800000ul; // 4.2949673E9f (4294967296)
  55. yield return 0x4F7FFFFF4F7FFFFFul; // 4.29496704E9f (4294967040)
  56. yield return 0xFF7FFFFFFF7FFFFFul; // -Max Normal (float.MinValue)
  57. yield return 0x8080000080800000ul; // -Min Normal
  58. yield return 0x807FFFFF807FFFFFul; // -Max Subnormal
  59. yield return 0x8000000180000001ul; // -Min Subnormal (-float.Epsilon)
  60. yield return 0x7F7FFFFF7F7FFFFFul; // +Max Normal (float.MaxValue)
  61. yield return 0x0080000000800000ul; // +Min Normal
  62. yield return 0x007FFFFF007FFFFFul; // +Max Subnormal
  63. yield return 0x0000000100000001ul; // +Min Subnormal (float.Epsilon)
  64. if (!NoZeros)
  65. {
  66. yield return 0x8000000080000000ul; // -Zero
  67. yield return 0x0000000000000000ul; // +Zero
  68. }
  69. if (!NoInfs)
  70. {
  71. yield return 0xFF800000FF800000ul; // -Infinity
  72. yield return 0x7F8000007F800000ul; // +Infinity
  73. }
  74. if (!NoNaNs)
  75. {
  76. yield return 0xFFC00000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
  77. yield return 0xFFBFFFFFFFBFFFFFul; // -SNaN (all ones payload)
  78. yield return 0x7FC000007FC00000ul; // +QNaN (all zeros payload) (-float.NaN) (DefaultNaN)
  79. yield return 0x7FBFFFFF7FBFFFFFul; // +SNaN (all ones payload)
  80. }
  81. for (int cnt = 1; cnt <= RndCnt; cnt++)
  82. {
  83. ulong rnd1 = (uint)BitConverter.SingleToInt32Bits(
  84. (float)((int)TestContext.CurrentContext.Random.NextUInt()));
  85. ulong rnd2 = (uint)BitConverter.SingleToInt32Bits(
  86. (float)((uint)TestContext.CurrentContext.Random.NextUInt()));
  87. ulong rnd3 = GenNormalS();
  88. ulong rnd4 = GenSubnormalS();
  89. yield return (rnd1 << 32) | rnd1;
  90. yield return (rnd2 << 32) | rnd2;
  91. yield return (rnd3 << 32) | rnd3;
  92. yield return (rnd4 << 32) | rnd4;
  93. }
  94. }
  95. private static IEnumerable<ulong> _1D_F_X_()
  96. {
  97. // long
  98. yield return 0xC3E0000000000001ul; // -9.2233720368547780E18d (-9223372036854778000)
  99. yield return 0xC3E0000000000000ul; // -9.2233720368547760E18d (-9223372036854776000)
  100. yield return 0xC3DFFFFFFFFFFFFFul; // -9.2233720368547750E18d (-9223372036854775000)
  101. yield return 0x43E0000000000001ul; // 9.2233720368547780E18d (9223372036854778000)
  102. yield return 0x43E0000000000000ul; // 9.2233720368547760E18d (9223372036854776000)
  103. yield return 0x43DFFFFFFFFFFFFFul; // 9.2233720368547750E18d (9223372036854775000)
  104. // ulong
  105. yield return 0x43F0000000000001ul; // 1.8446744073709556e19d (18446744073709556000)
  106. yield return 0x43F0000000000000ul; // 1.8446744073709552E19d (18446744073709552000)
  107. yield return 0x43EFFFFFFFFFFFFFul; // 1.8446744073709550e19d (18446744073709550000)
  108. yield return 0xFFEFFFFFFFFFFFFFul; // -Max Normal (double.MinValue)
  109. yield return 0x8010000000000000ul; // -Min Normal
  110. yield return 0x800FFFFFFFFFFFFFul; // -Max Subnormal
  111. yield return 0x8000000000000001ul; // -Min Subnormal (-double.Epsilon)
  112. yield return 0x7FEFFFFFFFFFFFFFul; // +Max Normal (double.MaxValue)
  113. yield return 0x0010000000000000ul; // +Min Normal
  114. yield return 0x000FFFFFFFFFFFFFul; // +Max Subnormal
  115. yield return 0x0000000000000001ul; // +Min Subnormal (double.Epsilon)
  116. if (!NoZeros)
  117. {
  118. yield return 0x8000000000000000ul; // -Zero
  119. yield return 0x0000000000000000ul; // +Zero
  120. }
  121. if (!NoInfs)
  122. {
  123. yield return 0xFFF0000000000000ul; // -Infinity
  124. yield return 0x7FF0000000000000ul; // +Infinity
  125. }
  126. if (!NoNaNs)
  127. {
  128. yield return 0xFFF8000000000000ul; // -QNaN (all zeros payload) (double.NaN)
  129. yield return 0xFFF7FFFFFFFFFFFFul; // -SNaN (all ones payload)
  130. yield return 0x7FF8000000000000ul; // +QNaN (all zeros payload) (-double.NaN) (DefaultNaN)
  131. yield return 0x7FF7FFFFFFFFFFFFul; // +SNaN (all ones payload)
  132. }
  133. for (int cnt = 1; cnt <= RndCnt; cnt++)
  134. {
  135. ulong rnd1 = (ulong)BitConverter.DoubleToInt64Bits(
  136. (double)((long)TestContext.CurrentContext.Random.NextULong()));
  137. ulong rnd2 = (ulong)BitConverter.DoubleToInt64Bits(
  138. (double)((ulong)TestContext.CurrentContext.Random.NextULong()));
  139. ulong rnd3 = GenNormalD();
  140. ulong rnd4 = GenSubnormalD();
  141. yield return rnd1;
  142. yield return rnd2;
  143. yield return rnd3;
  144. yield return rnd4;
  145. }
  146. }
  147. #endregion
  148. #region "ValueSource (Opcodes)"
  149. private static uint[] _F_Cvt_Z_SU_V_Fixed_2S_4S_()
  150. {
  151. return new uint[]
  152. {
  153. 0x0F20FC00u, // FCVTZS V0.2S, V0.2S, #32
  154. 0x2F20FC00u // FCVTZU V0.2S, V0.2S, #32
  155. };
  156. }
  157. private static uint[] _F_Cvt_Z_SU_V_Fixed_2D_()
  158. {
  159. return new uint[]
  160. {
  161. 0x4F40FC00u, // FCVTZS V0.2D, V0.2D, #64
  162. 0x6F40FC00u // FCVTZU V0.2D, V0.2D, #64
  163. };
  164. }
  165. private static uint[] _SU_Cvt_F_V_Fixed_2S_4S_()
  166. {
  167. return new uint[]
  168. {
  169. 0x0F20E400u, // SCVTF V0.2S, V0.2S, #32
  170. 0x2F20E400u // UCVTF V0.2S, V0.2S, #32
  171. };
  172. }
  173. private static uint[] _SU_Cvt_F_V_Fixed_2D_()
  174. {
  175. return new uint[]
  176. {
  177. 0x4F40E400u, // SCVTF V0.2D, V0.2D, #64
  178. 0x6F40E400u // UCVTF V0.2D, V0.2D, #64
  179. };
  180. }
  181. private static uint[] _Shl_Sli_S_D_()
  182. {
  183. return new uint[]
  184. {
  185. 0x5F405400u, // SHL D0, D0, #0
  186. //0x7F405400u // SLI D0, D0, #0
  187. };
  188. }
  189. private static uint[] _Shl_Sli_V_8B_16B_()
  190. {
  191. return new uint[]
  192. {
  193. 0x0F085400u, // SHL V0.8B, V0.8B, #0
  194. 0x2F085400u // SLI V0.8B, V0.8B, #0
  195. };
  196. }
  197. private static uint[] _Shl_Sli_V_4H_8H_()
  198. {
  199. return new uint[]
  200. {
  201. 0x0F105400u, // SHL V0.4H, V0.4H, #0
  202. 0x2F105400u // SLI V0.4H, V0.4H, #0
  203. };
  204. }
  205. private static uint[] _Shl_Sli_V_2S_4S_()
  206. {
  207. return new uint[]
  208. {
  209. 0x0F205400u, // SHL V0.2S, V0.2S, #0
  210. 0x2F205400u // SLI V0.2S, V0.2S, #0
  211. };
  212. }
  213. private static uint[] _Shl_Sli_V_2D_()
  214. {
  215. return new uint[]
  216. {
  217. 0x4F405400u, // SHL V0.2D, V0.2D, #0
  218. 0x6F405400u // SLI V0.2D, V0.2D, #0
  219. };
  220. }
  221. private static uint[] _SU_Shll_V_8B8H_16B8H_()
  222. {
  223. return new uint[]
  224. {
  225. 0x0F08A400u, // SSHLL V0.8H, V0.8B, #0
  226. 0x2F08A400u // USHLL V0.8H, V0.8B, #0
  227. };
  228. }
  229. private static uint[] _SU_Shll_V_4H4S_8H4S_()
  230. {
  231. return new uint[]
  232. {
  233. 0x0F10A400u, // SSHLL V0.4S, V0.4H, #0
  234. 0x2F10A400u // USHLL V0.4S, V0.4H, #0
  235. };
  236. }
  237. private static uint[] _SU_Shll_V_2S2D_4S2D_()
  238. {
  239. return new uint[]
  240. {
  241. 0x0F20A400u, // SSHLL V0.2D, V0.2S, #0
  242. 0x2F20A400u // USHLL V0.2D, V0.2S, #0
  243. };
  244. }
  245. private static uint[] _ShrImm_S_D_()
  246. {
  247. return new uint[]
  248. {
  249. 0x5F402400u, // SRSHR D0, D0, #64
  250. 0x5F403400u, // SRSRA D0, D0, #64
  251. 0x5F400400u, // SSHR D0, D0, #64
  252. 0x5F401400u, // SSRA D0, D0, #64
  253. 0x7F402400u, // URSHR D0, D0, #64
  254. 0x7F403400u, // URSRA D0, D0, #64
  255. 0x7F400400u, // USHR D0, D0, #64
  256. 0x7F401400u // USRA D0, D0, #64
  257. };
  258. }
  259. private static uint[] _ShrImm_V_8B_16B_()
  260. {
  261. return new uint[]
  262. {
  263. 0x0F082400u, // SRSHR V0.8B, V0.8B, #8
  264. 0x0F083400u, // SRSRA V0.8B, V0.8B, #8
  265. 0x0F080400u, // SSHR V0.8B, V0.8B, #8
  266. 0x0F081400u, // SSRA V0.8B, V0.8B, #8
  267. 0x2F082400u, // URSHR V0.8B, V0.8B, #8
  268. 0x2F083400u, // URSRA V0.8B, V0.8B, #8
  269. 0x2F080400u, // USHR V0.8B, V0.8B, #8
  270. 0x2F081400u // USRA V0.8B, V0.8B, #8
  271. };
  272. }
  273. private static uint[] _ShrImm_V_4H_8H_()
  274. {
  275. return new uint[]
  276. {
  277. 0x0F102400u, // SRSHR V0.4H, V0.4H, #16
  278. 0x0F103400u, // SRSRA V0.4H, V0.4H, #16
  279. 0x0F100400u, // SSHR V0.4H, V0.4H, #16
  280. 0x0F101400u, // SSRA V0.4H, V0.4H, #16
  281. 0x2F102400u, // URSHR V0.4H, V0.4H, #16
  282. 0x2F103400u, // URSRA V0.4H, V0.4H, #16
  283. 0x2F100400u, // USHR V0.4H, V0.4H, #16
  284. 0x2F101400u // USRA V0.4H, V0.4H, #16
  285. };
  286. }
  287. private static uint[] _ShrImm_V_2S_4S_()
  288. {
  289. return new uint[]
  290. {
  291. 0x0F202400u, // SRSHR V0.2S, V0.2S, #32
  292. 0x0F203400u, // SRSRA V0.2S, V0.2S, #32
  293. 0x0F200400u, // SSHR V0.2S, V0.2S, #32
  294. 0x0F201400u, // SSRA V0.2S, V0.2S, #32
  295. 0x2F202400u, // URSHR V0.2S, V0.2S, #32
  296. 0x2F203400u, // URSRA V0.2S, V0.2S, #32
  297. 0x2F200400u, // USHR V0.2S, V0.2S, #32
  298. 0x2F201400u // USRA V0.2S, V0.2S, #32
  299. };
  300. }
  301. private static uint[] _ShrImm_V_2D_()
  302. {
  303. return new uint[]
  304. {
  305. 0x4F402400u, // SRSHR V0.2D, V0.2D, #64
  306. 0x4F403400u, // SRSRA V0.2D, V0.2D, #64
  307. 0x4F400400u, // SSHR V0.2D, V0.2D, #64
  308. 0x4F401400u, // SSRA V0.2D, V0.2D, #64
  309. 0x6F402400u, // URSHR V0.2D, V0.2D, #64
  310. 0x6F403400u, // URSRA V0.2D, V0.2D, #64
  311. 0x6F400400u, // USHR V0.2D, V0.2D, #64
  312. 0x6F401400u // USRA V0.2D, V0.2D, #64
  313. };
  314. }
  315. private static uint[] _ShrImmNarrow_V_8H8B_8H16B_()
  316. {
  317. return new uint[]
  318. {
  319. 0x0F088C00u, // RSHRN V0.8B, V0.8H, #8
  320. 0x0F088400u // SHRN V0.8B, V0.8H, #8
  321. };
  322. }
  323. private static uint[] _ShrImmNarrow_V_4S4H_4S8H_()
  324. {
  325. return new uint[]
  326. {
  327. 0x0F108C00u, // RSHRN V0.4H, V0.4S, #16
  328. 0x0F108400u // SHRN V0.4H, V0.4S, #16
  329. };
  330. }
  331. private static uint[] _ShrImmNarrow_V_2D2S_2D4S_()
  332. {
  333. return new uint[]
  334. {
  335. 0x0F208C00u, // RSHRN V0.2S, V0.2D, #32
  336. 0x0F208400u // SHRN V0.2S, V0.2D, #32
  337. };
  338. }
  339. private static uint[] _ShrImmSaturatingNarrow_S_HB_()
  340. {
  341. return new uint[]
  342. {
  343. 0x5F089C00u, // SQRSHRN B0, H0, #8
  344. 0x7F089C00u, // UQRSHRN B0, H0, #8
  345. 0x7F088C00u, // SQRSHRUN B0, H0, #8
  346. 0x5F089400u, // SQSHRN B0, H0, #8
  347. 0x7F089400u, // UQSHRN B0, H0, #8
  348. 0x7F088400u // SQSHRUN B0, H0, #8
  349. };
  350. }
  351. private static uint[] _ShrImmSaturatingNarrow_S_SH_()
  352. {
  353. return new uint[]
  354. {
  355. 0x5F109C00u, // SQRSHRN H0, S0, #16
  356. 0x7F109C00u, // UQRSHRN H0, S0, #16
  357. 0x7F108C00u, // SQRSHRUN H0, S0, #16
  358. 0x5F109400u, // SQSHRN H0, S0, #16
  359. 0x7F109400u, // UQSHRN H0, S0, #16
  360. 0x7F108400u // SQSHRUN H0, S0, #16
  361. };
  362. }
  363. private static uint[] _ShrImmSaturatingNarrow_S_DS_()
  364. {
  365. return new uint[]
  366. {
  367. 0x5F209C00u, // SQRSHRN S0, D0, #32
  368. 0x7F209C00u, // UQRSHRN S0, D0, #32
  369. 0x7F208C00u, // SQRSHRUN S0, D0, #32
  370. 0x5F209400u, // SQSHRN S0, D0, #32
  371. 0x7F209400u, // UQSHRN S0, D0, #32
  372. 0x7F208400u // SQSHRUN S0, D0, #32
  373. };
  374. }
  375. private static uint[] _ShrImmSaturatingNarrow_V_8H8B_8H16B_()
  376. {
  377. return new uint[]
  378. {
  379. 0x0F089C00u, // SQRSHRN V0.8B, V0.8H, #8
  380. 0x2F089C00u, // UQRSHRN V0.8B, V0.8H, #8
  381. 0x2F088C00u, // SQRSHRUN V0.8B, V0.8H, #8
  382. 0x0F089400u, // SQSHRN V0.8B, V0.8H, #8
  383. 0x2F089400u, // UQSHRN V0.8B, V0.8H, #8
  384. 0x2F088400u // SQSHRUN V0.8B, V0.8H, #8
  385. };
  386. }
  387. private static uint[] _ShrImmSaturatingNarrow_V_4S4H_4S8H_()
  388. {
  389. return new uint[]
  390. {
  391. 0x0F109C00u, // SQRSHRN V0.4H, V0.4S, #16
  392. 0x2F109C00u, // UQRSHRN V0.4H, V0.4S, #16
  393. 0x2F108C00u, // SQRSHRUN V0.4H, V0.4S, #16
  394. 0x0F109400u, // SQSHRN V0.4H, V0.4S, #16
  395. 0x2F109400u, // UQSHRN V0.4H, V0.4S, #16
  396. 0x2F108400u // SQSHRUN V0.4H, V0.4S, #16
  397. };
  398. }
  399. private static uint[] _ShrImmSaturatingNarrow_V_2D2S_2D4S_()
  400. {
  401. return new uint[]
  402. {
  403. 0x0F209C00u, // SQRSHRN V0.2S, V0.2D, #32
  404. 0x2F209C00u, // UQRSHRN V0.2S, V0.2D, #32
  405. 0x2F208C00u, // SQRSHRUN V0.2S, V0.2D, #32
  406. 0x0F209400u, // SQSHRN V0.2S, V0.2D, #32
  407. 0x2F209400u, // UQSHRN V0.2S, V0.2D, #32
  408. 0x2F208400u // SQSHRUN V0.2S, V0.2D, #32
  409. };
  410. }
  411. #endregion
  412. private const int RndCnt = 2;
  413. private const int RndCntFBits = 2;
  414. private const int RndCntShift = 2;
  415. private static readonly bool NoZeros = false;
  416. private static readonly bool NoInfs = false;
  417. private static readonly bool NoNaNs = false;
  418. [Test, Pairwise] [Explicit]
  419. public void F_Cvt_Z_SU_V_Fixed_2S_4S([ValueSource("_F_Cvt_Z_SU_V_Fixed_2S_4S_")] uint opcodes,
  420. [Values(0u)] uint rd,
  421. [Values(1u, 0u)] uint rn,
  422. [ValueSource("_2S_F_W_")] ulong z,
  423. [ValueSource("_2S_F_W_")] ulong a,
  424. [Values(1u, 32u)] [Random(2u, 31u, RndCntFBits)] uint fBits,
  425. [Values(0b0u, 0b1u)] uint q) // <2S, 4S>
  426. {
  427. uint immHb = (64 - fBits) & 0x7F;
  428. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  429. opcodes |= (immHb << 16);
  430. opcodes |= ((q & 1) << 30);
  431. V128 v0 = MakeVectorE0E1(z, z);
  432. V128 v1 = MakeVectorE0E1(a, a * q);
  433. SingleOpcode(opcodes, v0: v0, v1: v1);
  434. CompareAgainstUnicorn();
  435. }
  436. [Test, Pairwise] [Explicit]
  437. public void F_Cvt_Z_SU_V_Fixed_2D([ValueSource("_F_Cvt_Z_SU_V_Fixed_2D_")] uint opcodes,
  438. [Values(0u)] uint rd,
  439. [Values(1u, 0u)] uint rn,
  440. [ValueSource("_1D_F_X_")] ulong z,
  441. [ValueSource("_1D_F_X_")] ulong a,
  442. [Values(1u, 64u)] [Random(2u, 63u, RndCntFBits)] uint fBits)
  443. {
  444. uint immHb = (128 - fBits) & 0x7F;
  445. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  446. opcodes |= (immHb << 16);
  447. V128 v0 = MakeVectorE0E1(z, z);
  448. V128 v1 = MakeVectorE0E1(a, a);
  449. SingleOpcode(opcodes, v0: v0, v1: v1);
  450. CompareAgainstUnicorn();
  451. }
  452. [Test, Pairwise] [Explicit]
  453. public void SU_Cvt_F_V_Fixed_2S_4S([ValueSource("_SU_Cvt_F_V_Fixed_2S_4S_")] uint opcodes,
  454. [Values(0u)] uint rd,
  455. [Values(1u, 0u)] uint rn,
  456. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  457. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  458. [Values(1u, 32u)] [Random(2u, 31u, RndCntFBits)] uint fBits,
  459. [Values(0b0u, 0b1u)] uint q) // <2S, 4S>
  460. {
  461. uint immHb = (64 - fBits) & 0x7F;
  462. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  463. opcodes |= (immHb << 16);
  464. opcodes |= ((q & 1) << 30);
  465. V128 v0 = MakeVectorE0E1(z, z);
  466. V128 v1 = MakeVectorE0E1(a, a * q);
  467. SingleOpcode(opcodes, v0: v0, v1: v1);
  468. CompareAgainstUnicorn();
  469. }
  470. [Test, Pairwise] [Explicit]
  471. public void SU_Cvt_F_V_Fixed_2D([ValueSource("_SU_Cvt_F_V_Fixed_2D_")] uint opcodes,
  472. [Values(0u)] uint rd,
  473. [Values(1u, 0u)] uint rn,
  474. [ValueSource("_1D_")] [Random(RndCnt)] ulong z,
  475. [ValueSource("_1D_")] [Random(RndCnt)] ulong a,
  476. [Values(1u, 64u)] [Random(2u, 63u, RndCntFBits)] uint fBits)
  477. {
  478. uint immHb = (128 - fBits) & 0x7F;
  479. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  480. opcodes |= (immHb << 16);
  481. V128 v0 = MakeVectorE0E1(z, z);
  482. V128 v1 = MakeVectorE0E1(a, a);
  483. SingleOpcode(opcodes, v0: v0, v1: v1);
  484. CompareAgainstUnicorn(fpTolerances: FpTolerances.UpToOneUlpsD); // unsigned
  485. }
  486. [Test, Pairwise]
  487. public void Shl_Sli_S_D([ValueSource("_Shl_Sli_S_D_")] uint opcodes,
  488. [Values(0u)] uint rd,
  489. [Values(1u, 0u)] uint rn,
  490. [ValueSource("_1D_")] [Random(RndCnt)] ulong z,
  491. [ValueSource("_1D_")] [Random(RndCnt)] ulong a,
  492. [Values(0u, 63u)] [Random(1u, 62u, RndCntShift)] uint shift)
  493. {
  494. uint immHb = (64 + shift) & 0x7F;
  495. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  496. opcodes |= (immHb << 16);
  497. V128 v0 = MakeVectorE0E1(z, z);
  498. V128 v1 = MakeVectorE0(a);
  499. SingleOpcode(opcodes, v0: v0, v1: v1);
  500. CompareAgainstUnicorn();
  501. }
  502. [Test, Pairwise]
  503. public void Shl_Sli_V_8B_16B([ValueSource("_Shl_Sli_V_8B_16B_")] uint opcodes,
  504. [Values(0u)] uint rd,
  505. [Values(1u, 0u)] uint rn,
  506. [ValueSource("_8B_")] [Random(RndCnt)] ulong z,
  507. [ValueSource("_8B_")] [Random(RndCnt)] ulong a,
  508. [Values(0u, 7u)] [Random(1u, 6u, RndCntShift)] uint shift,
  509. [Values(0b0u, 0b1u)] uint q) // <8B, 16B>
  510. {
  511. uint immHb = (8 + shift) & 0x7F;
  512. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  513. opcodes |= (immHb << 16);
  514. opcodes |= ((q & 1) << 30);
  515. V128 v0 = MakeVectorE0E1(z, z);
  516. V128 v1 = MakeVectorE0E1(a, a * q);
  517. SingleOpcode(opcodes, v0: v0, v1: v1);
  518. CompareAgainstUnicorn();
  519. }
  520. [Test, Pairwise]
  521. public void Shl_Sli_V_4H_8H([ValueSource("_Shl_Sli_V_4H_8H_")] uint opcodes,
  522. [Values(0u)] uint rd,
  523. [Values(1u, 0u)] uint rn,
  524. [ValueSource("_4H_")] [Random(RndCnt)] ulong z,
  525. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  526. [Values(0u, 15u)] [Random(1u, 14u, RndCntShift)] uint shift,
  527. [Values(0b0u, 0b1u)] uint q) // <4H, 8H>
  528. {
  529. uint immHb = (16 + shift) & 0x7F;
  530. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  531. opcodes |= (immHb << 16);
  532. opcodes |= ((q & 1) << 30);
  533. V128 v0 = MakeVectorE0E1(z, z);
  534. V128 v1 = MakeVectorE0E1(a, a * q);
  535. SingleOpcode(opcodes, v0: v0, v1: v1);
  536. CompareAgainstUnicorn();
  537. }
  538. [Test, Pairwise]
  539. public void Shl_Sli_V_2S_4S([ValueSource("_Shl_Sli_V_2S_4S_")] uint opcodes,
  540. [Values(0u)] uint rd,
  541. [Values(1u, 0u)] uint rn,
  542. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  543. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  544. [Values(0u, 31u)] [Random(1u, 30u, RndCntShift)] uint shift,
  545. [Values(0b0u, 0b1u)] uint q) // <2S, 4S>
  546. {
  547. uint immHb = (32 + shift) & 0x7F;
  548. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  549. opcodes |= (immHb << 16);
  550. opcodes |= ((q & 1) << 30);
  551. V128 v0 = MakeVectorE0E1(z, z);
  552. V128 v1 = MakeVectorE0E1(a, a * q);
  553. SingleOpcode(opcodes, v0: v0, v1: v1);
  554. CompareAgainstUnicorn();
  555. }
  556. [Test, Pairwise]
  557. public void Shl_Sli_V_2D([ValueSource("_Shl_Sli_V_2D_")] uint opcodes,
  558. [Values(0u)] uint rd,
  559. [Values(1u, 0u)] uint rn,
  560. [ValueSource("_1D_")] [Random(RndCnt)] ulong z,
  561. [ValueSource("_1D_")] [Random(RndCnt)] ulong a,
  562. [Values(0u, 63u)] [Random(1u, 62u, RndCntShift)] uint shift)
  563. {
  564. uint immHb = (64 + shift) & 0x7F;
  565. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  566. opcodes |= (immHb << 16);
  567. V128 v0 = MakeVectorE0E1(z, z);
  568. V128 v1 = MakeVectorE0E1(a, a);
  569. SingleOpcode(opcodes, v0: v0, v1: v1);
  570. CompareAgainstUnicorn();
  571. }
  572. [Test, Pairwise]
  573. public void SU_Shll_V_8B8H_16B8H([ValueSource("_SU_Shll_V_8B8H_16B8H_")] uint opcodes,
  574. [Values(0u)] uint rd,
  575. [Values(1u, 0u)] uint rn,
  576. [ValueSource("_8B_")] [Random(RndCnt)] ulong z,
  577. [ValueSource("_8B_")] [Random(RndCnt)] ulong a,
  578. [Values(0u, 7u)] [Random(1u, 6u, RndCntShift)] uint shift,
  579. [Values(0b0u, 0b1u)] uint q) // <8B8H, 16B8H>
  580. {
  581. uint immHb = (8 + shift) & 0x7F;
  582. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  583. opcodes |= (immHb << 16);
  584. opcodes |= ((q & 1) << 30);
  585. V128 v0 = MakeVectorE0E1(z, z);
  586. V128 v1 = MakeVectorE0E1(q == 0u ? a : 0ul, q == 1u ? a : 0ul);
  587. SingleOpcode(opcodes, v0: v0, v1: v1);
  588. CompareAgainstUnicorn();
  589. }
  590. [Test, Pairwise]
  591. public void SU_Shll_V_4H4S_8H4S([ValueSource("_SU_Shll_V_4H4S_8H4S_")] uint opcodes,
  592. [Values(0u)] uint rd,
  593. [Values(1u, 0u)] uint rn,
  594. [ValueSource("_4H_")] [Random(RndCnt)] ulong z,
  595. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  596. [Values(0u, 15u)] [Random(1u, 14u, RndCntShift)] uint shift,
  597. [Values(0b0u, 0b1u)] uint q) // <4H4S, 8H4S>
  598. {
  599. uint immHb = (16 + shift) & 0x7F;
  600. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  601. opcodes |= (immHb << 16);
  602. opcodes |= ((q & 1) << 30);
  603. V128 v0 = MakeVectorE0E1(z, z);
  604. V128 v1 = MakeVectorE0E1(q == 0u ? a : 0ul, q == 1u ? a : 0ul);
  605. SingleOpcode(opcodes, v0: v0, v1: v1);
  606. CompareAgainstUnicorn();
  607. }
  608. [Test, Pairwise]
  609. public void SU_Shll_V_2S2D_4S2D([ValueSource("_SU_Shll_V_2S2D_4S2D_")] uint opcodes,
  610. [Values(0u)] uint rd,
  611. [Values(1u, 0u)] uint rn,
  612. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  613. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  614. [Values(0u, 31u)] [Random(1u, 30u, RndCntShift)] uint shift,
  615. [Values(0b0u, 0b1u)] uint q) // <2S2D, 4S2D>
  616. {
  617. uint immHb = (32 + shift) & 0x7F;
  618. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  619. opcodes |= (immHb << 16);
  620. opcodes |= ((q & 1) << 30);
  621. V128 v0 = MakeVectorE0E1(z, z);
  622. V128 v1 = MakeVectorE0E1(q == 0u ? a : 0ul, q == 1u ? a : 0ul);
  623. SingleOpcode(opcodes, v0: v0, v1: v1);
  624. CompareAgainstUnicorn();
  625. }
  626. [Test, Pairwise]
  627. public void ShrImm_S_D([ValueSource("_ShrImm_S_D_")] uint opcodes,
  628. [Values(0u)] uint rd,
  629. [Values(1u, 0u)] uint rn,
  630. [ValueSource("_1D_")] [Random(RndCnt)] ulong z,
  631. [ValueSource("_1D_")] [Random(RndCnt)] ulong a,
  632. [Values(1u, 64u)] [Random(2u, 63u, RndCntShift)] uint shift)
  633. {
  634. uint immHb = (128 - shift) & 0x7F;
  635. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  636. opcodes |= (immHb << 16);
  637. V128 v0 = MakeVectorE0E1(z, z);
  638. V128 v1 = MakeVectorE0(a);
  639. SingleOpcode(opcodes, v0: v0, v1: v1);
  640. CompareAgainstUnicorn();
  641. }
  642. [Test, Pairwise]
  643. public void ShrImm_V_8B_16B([ValueSource("_ShrImm_V_8B_16B_")] uint opcodes,
  644. [Values(0u)] uint rd,
  645. [Values(1u, 0u)] uint rn,
  646. [ValueSource("_8B_")] [Random(RndCnt)] ulong z,
  647. [ValueSource("_8B_")] [Random(RndCnt)] ulong a,
  648. [Values(1u, 8u)] [Random(2u, 7u, RndCntShift)] uint shift,
  649. [Values(0b0u, 0b1u)] uint q) // <8B, 16B>
  650. {
  651. uint immHb = (16 - shift) & 0x7F;
  652. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  653. opcodes |= (immHb << 16);
  654. opcodes |= ((q & 1) << 30);
  655. V128 v0 = MakeVectorE0E1(z, z);
  656. V128 v1 = MakeVectorE0E1(a, a * q);
  657. SingleOpcode(opcodes, v0: v0, v1: v1);
  658. CompareAgainstUnicorn();
  659. }
  660. [Test, Pairwise]
  661. public void ShrImm_V_4H_8H([ValueSource("_ShrImm_V_4H_8H_")] uint opcodes,
  662. [Values(0u)] uint rd,
  663. [Values(1u, 0u)] uint rn,
  664. [ValueSource("_4H_")] [Random(RndCnt)] ulong z,
  665. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  666. [Values(1u, 16u)] [Random(2u, 15u, RndCntShift)] uint shift,
  667. [Values(0b0u, 0b1u)] uint q) // <4H, 8H>
  668. {
  669. uint immHb = (32 - shift) & 0x7F;
  670. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  671. opcodes |= (immHb << 16);
  672. opcodes |= ((q & 1) << 30);
  673. V128 v0 = MakeVectorE0E1(z, z);
  674. V128 v1 = MakeVectorE0E1(a, a * q);
  675. SingleOpcode(opcodes, v0: v0, v1: v1);
  676. CompareAgainstUnicorn();
  677. }
  678. [Test, Pairwise]
  679. public void ShrImm_V_2S_4S([ValueSource("_ShrImm_V_2S_4S_")] uint opcodes,
  680. [Values(0u)] uint rd,
  681. [Values(1u, 0u)] uint rn,
  682. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  683. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  684. [Values(1u, 32u)] [Random(2u, 31u, RndCntShift)] uint shift,
  685. [Values(0b0u, 0b1u)] uint q) // <2S, 4S>
  686. {
  687. uint immHb = (64 - shift) & 0x7F;
  688. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  689. opcodes |= (immHb << 16);
  690. opcodes |= ((q & 1) << 30);
  691. V128 v0 = MakeVectorE0E1(z, z);
  692. V128 v1 = MakeVectorE0E1(a, a * q);
  693. SingleOpcode(opcodes, v0: v0, v1: v1);
  694. CompareAgainstUnicorn();
  695. }
  696. [Test, Pairwise]
  697. public void ShrImm_V_2D([ValueSource("_ShrImm_V_2D_")] uint opcodes,
  698. [Values(0u)] uint rd,
  699. [Values(1u, 0u)] uint rn,
  700. [ValueSource("_1D_")] [Random(RndCnt)] ulong z,
  701. [ValueSource("_1D_")] [Random(RndCnt)] ulong a,
  702. [Values(1u, 64u)] [Random(2u, 63u, RndCntShift)] uint shift)
  703. {
  704. uint immHb = (128 - shift) & 0x7F;
  705. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  706. opcodes |= (immHb << 16);
  707. V128 v0 = MakeVectorE0E1(z, z);
  708. V128 v1 = MakeVectorE0E1(a, a);
  709. SingleOpcode(opcodes, v0: v0, v1: v1);
  710. CompareAgainstUnicorn();
  711. }
  712. [Test, Pairwise]
  713. public void ShrImmNarrow_V_8H8B_8H16B([ValueSource("_ShrImmNarrow_V_8H8B_8H16B_")] uint opcodes,
  714. [Values(0u)] uint rd,
  715. [Values(1u, 0u)] uint rn,
  716. [ValueSource("_4H_")] [Random(RndCnt)] ulong z,
  717. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  718. [Values(1u, 8u)] [Random(2u, 7u, RndCntShift)] uint shift,
  719. [Values(0b0u, 0b1u)] uint q) // <8H8B, 8H16B>
  720. {
  721. uint immHb = (16 - shift) & 0x7F;
  722. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  723. opcodes |= (immHb << 16);
  724. opcodes |= ((q & 1) << 30);
  725. V128 v0 = MakeVectorE0E1(z, z);
  726. V128 v1 = MakeVectorE0E1(a, a);
  727. SingleOpcode(opcodes, v0: v0, v1: v1);
  728. CompareAgainstUnicorn();
  729. }
  730. [Test, Pairwise]
  731. public void ShrImmNarrow_V_4S4H_4S8H([ValueSource("_ShrImmNarrow_V_4S4H_4S8H_")] uint opcodes,
  732. [Values(0u)] uint rd,
  733. [Values(1u, 0u)] uint rn,
  734. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  735. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  736. [Values(1u, 16u)] [Random(2u, 15u, RndCntShift)] uint shift,
  737. [Values(0b0u, 0b1u)] uint q) // <4S4H, 4S8H>
  738. {
  739. uint immHb = (32 - shift) & 0x7F;
  740. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  741. opcodes |= (immHb << 16);
  742. opcodes |= ((q & 1) << 30);
  743. V128 v0 = MakeVectorE0E1(z, z);
  744. V128 v1 = MakeVectorE0E1(a, a);
  745. SingleOpcode(opcodes, v0: v0, v1: v1);
  746. CompareAgainstUnicorn();
  747. }
  748. [Test, Pairwise]
  749. public void ShrImmNarrow_V_2D2S_2D4S([ValueSource("_ShrImmNarrow_V_2D2S_2D4S_")] uint opcodes,
  750. [Values(0u)] uint rd,
  751. [Values(1u, 0u)] uint rn,
  752. [ValueSource("_1D_")] [Random(RndCnt)] ulong z,
  753. [ValueSource("_1D_")] [Random(RndCnt)] ulong a,
  754. [Values(1u, 32u)] [Random(2u, 31u, RndCntShift)] uint shift,
  755. [Values(0b0u, 0b1u)] uint q) // <2D2S, 2D4S>
  756. {
  757. uint immHb = (64 - shift) & 0x7F;
  758. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  759. opcodes |= (immHb << 16);
  760. opcodes |= ((q & 1) << 30);
  761. V128 v0 = MakeVectorE0E1(z, z);
  762. V128 v1 = MakeVectorE0E1(a, a);
  763. SingleOpcode(opcodes, v0: v0, v1: v1);
  764. CompareAgainstUnicorn();
  765. }
  766. [Test, Pairwise]
  767. public void ShrImmSaturatingNarrow_S_HB([ValueSource("_ShrImmSaturatingNarrow_S_HB_")] uint opcodes,
  768. [Values(0u)] uint rd,
  769. [Values(1u, 0u)] uint rn,
  770. [ValueSource("_1H_")] [Random(RndCnt)] ulong z,
  771. [ValueSource("_1H_")] [Random(RndCnt)] ulong a,
  772. [Values(1u, 8u)] [Random(2u, 7u, RndCntShift)] uint shift)
  773. {
  774. uint immHb = (16 - shift) & 0x7F;
  775. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  776. opcodes |= (immHb << 16);
  777. V128 v0 = MakeVectorE0E1(z, z);
  778. V128 v1 = MakeVectorE0(a);
  779. SingleOpcode(opcodes, v0: v0, v1: v1);
  780. CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
  781. }
  782. [Test, Pairwise]
  783. public void ShrImmSaturatingNarrow_S_SH([ValueSource("_ShrImmSaturatingNarrow_S_SH_")] uint opcodes,
  784. [Values(0u)] uint rd,
  785. [Values(1u, 0u)] uint rn,
  786. [ValueSource("_1S_")] [Random(RndCnt)] ulong z,
  787. [ValueSource("_1S_")] [Random(RndCnt)] ulong a,
  788. [Values(1u, 16u)] [Random(2u, 15u, RndCntShift)] uint shift)
  789. {
  790. uint immHb = (32 - shift) & 0x7F;
  791. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  792. opcodes |= (immHb << 16);
  793. V128 v0 = MakeVectorE0E1(z, z);
  794. V128 v1 = MakeVectorE0(a);
  795. SingleOpcode(opcodes, v0: v0, v1: v1);
  796. CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
  797. }
  798. [Test, Pairwise]
  799. public void ShrImmSaturatingNarrow_S_DS([ValueSource("_ShrImmSaturatingNarrow_S_DS_")] uint opcodes,
  800. [Values(0u)] uint rd,
  801. [Values(1u, 0u)] uint rn,
  802. [ValueSource("_1D_")] [Random(RndCnt)] ulong z,
  803. [ValueSource("_1D_")] [Random(RndCnt)] ulong a,
  804. [Values(1u, 32u)] [Random(2u, 31u, RndCntShift)] uint shift)
  805. {
  806. uint immHb = (64 - shift) & 0x7F;
  807. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  808. opcodes |= (immHb << 16);
  809. V128 v0 = MakeVectorE0E1(z, z);
  810. V128 v1 = MakeVectorE0(a);
  811. SingleOpcode(opcodes, v0: v0, v1: v1);
  812. CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
  813. }
  814. [Test, Pairwise]
  815. public void ShrImmSaturatingNarrow_V_8H8B_8H16B([ValueSource("_ShrImmSaturatingNarrow_V_8H8B_8H16B_")] uint opcodes,
  816. [Values(0u)] uint rd,
  817. [Values(1u, 0u)] uint rn,
  818. [ValueSource("_4H_")] [Random(RndCnt)] ulong z,
  819. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  820. [Values(1u, 8u)] [Random(2u, 7u, RndCntShift)] uint shift,
  821. [Values(0b0u, 0b1u)] uint q) // <8H8B, 8H16B>
  822. {
  823. uint immHb = (16 - shift) & 0x7F;
  824. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  825. opcodes |= (immHb << 16);
  826. opcodes |= ((q & 1) << 30);
  827. V128 v0 = MakeVectorE0E1(z, z);
  828. V128 v1 = MakeVectorE0(a);
  829. SingleOpcode(opcodes, v0: v0, v1: v1);
  830. CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
  831. }
  832. [Test, Pairwise]
  833. public void ShrImmSaturatingNarrow_V_4S4H_4S8H([ValueSource("_ShrImmSaturatingNarrow_V_4S4H_4S8H_")] uint opcodes,
  834. [Values(0u)] uint rd,
  835. [Values(1u, 0u)] uint rn,
  836. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  837. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  838. [Values(1u, 16u)] [Random(2u, 15u, RndCntShift)] uint shift,
  839. [Values(0b0u, 0b1u)] uint q) // <4S4H, 4S8H>
  840. {
  841. uint immHb = (32 - shift) & 0x7F;
  842. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  843. opcodes |= (immHb << 16);
  844. opcodes |= ((q & 1) << 30);
  845. V128 v0 = MakeVectorE0E1(z, z);
  846. V128 v1 = MakeVectorE0(a);
  847. SingleOpcode(opcodes, v0: v0, v1: v1);
  848. CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
  849. }
  850. [Test, Pairwise]
  851. public void ShrImmSaturatingNarrow_V_2D2S_2D4S([ValueSource("_ShrImmSaturatingNarrow_V_2D2S_2D4S_")] uint opcodes,
  852. [Values(0u)] uint rd,
  853. [Values(1u, 0u)] uint rn,
  854. [ValueSource("_1D_")] [Random(RndCnt)] ulong z,
  855. [ValueSource("_1D_")] [Random(RndCnt)] ulong a,
  856. [Values(1u, 32u)] [Random(2u, 31u, RndCntShift)] uint shift,
  857. [Values(0b0u, 0b1u)] uint q) // <2D2S, 2D4S>
  858. {
  859. uint immHb = (64 - shift) & 0x7F;
  860. opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
  861. opcodes |= (immHb << 16);
  862. opcodes |= ((q & 1) << 30);
  863. V128 v0 = MakeVectorE0E1(z, z);
  864. V128 v1 = MakeVectorE0(a);
  865. SingleOpcode(opcodes, v0: v0, v1: v1);
  866. CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
  867. }
  868. #endif
  869. }
  870. }