CpuTestAluRx.cs 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. #define AluRx
  2. using ChocolArm64.State;
  3. using NUnit.Framework;
  4. namespace Ryujinx.Tests.Cpu
  5. {
  6. [Category("AluRx")] // Tested: second half of 2018.
  7. public sealed class CpuTestAluRx : CpuTest
  8. {
  9. #if AluRx
  10. private const int RndCnt = 2;
  11. [Test, Pairwise, Description("ADD <Xd|SP>, <Xn|SP>, <X><m>{, <extend> {#<amount>}}")]
  12. public void Add_X_64bit([Values(0u, 31u)] uint Rd,
  13. [Values(1u, 31u)] uint Rn,
  14. [Values(2u, 31u)] uint Rm,
  15. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  16. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
  17. [Values((ulong)0x0000000000000000, (ulong)0x7FFFFFFFFFFFFFFF,
  18. (ulong)0x8000000000000000, (ulong)0xFFFFFFFFFFFFFFFF)] [Random(RndCnt)] ulong Xm,
  19. [Values(0b011u, 0b111u)] uint extend, // <LSL|UXTX, SXTX>
  20. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  21. {
  22. uint Opcode = 0x8B206000; // ADD X0, X0, X0, UXTX #0
  23. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  24. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  25. AThreadState ThreadState;
  26. if (Rn != 31)
  27. {
  28. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  29. ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Xm, X31: _X31);
  30. }
  31. else
  32. {
  33. ThreadState = SingleOpcode(Opcode, X31: Xn_SP, X2: Xm);
  34. }
  35. CompareAgainstUnicorn();
  36. }
  37. [Test, Pairwise, Description("ADD <Xd|SP>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
  38. public void Add_W_64bit([Values(0u, 31u)] uint Rd,
  39. [Values(1u, 31u)] uint Rn,
  40. [Values(2u, 31u)] uint Rm,
  41. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  42. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
  43. [Values((uint)0x00000000, (uint)0x7FFFFFFF,
  44. (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(RndCnt)] uint Wm,
  45. [Values(0b000u, 0b001u, 0b010u, // <UXTB, UXTH, UXTW,
  46. 0b100u, 0b101u, 0b110u)] uint extend, // SXTB, SXTH, SXTW>
  47. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  48. {
  49. uint Opcode = 0x8B200000; // ADD X0, X0, W0, UXTB #0
  50. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  51. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  52. AThreadState ThreadState;
  53. if (Rn != 31)
  54. {
  55. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  56. ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31);
  57. }
  58. else
  59. {
  60. ThreadState = SingleOpcode(Opcode, X31: Xn_SP, X2: Wm);
  61. }
  62. CompareAgainstUnicorn();
  63. }
  64. [Test, Pairwise, Description("ADD <Xd|SP>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
  65. public void Add_H_64bit([Values(0u, 31u)] uint Rd,
  66. [Values(1u, 31u)] uint Rn,
  67. [Values(2u, 31u)] uint Rm,
  68. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  69. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
  70. [Values((ushort)0x0000, (ushort)0x7FFF,
  71. (ushort)0x8000, (ushort)0xFFFF)] [Random(RndCnt)] ushort Wm,
  72. [Values(0b000u, 0b001u, 0b010u, // <UXTB, UXTH, UXTW,
  73. 0b100u, 0b101u, 0b110u)] uint extend, // SXTB, SXTH, SXTW>
  74. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  75. {
  76. uint Opcode = 0x8B200000; // ADD X0, X0, W0, UXTB #0
  77. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  78. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  79. AThreadState ThreadState;
  80. if (Rn != 31)
  81. {
  82. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  83. ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31);
  84. }
  85. else
  86. {
  87. ThreadState = SingleOpcode(Opcode, X31: Xn_SP, X2: Wm);
  88. }
  89. CompareAgainstUnicorn();
  90. }
  91. [Test, Pairwise, Description("ADD <Xd|SP>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
  92. public void Add_B_64bit([Values(0u, 31u)] uint Rd,
  93. [Values(1u, 31u)] uint Rn,
  94. [Values(2u, 31u)] uint Rm,
  95. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  96. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
  97. [Values((byte)0x00, (byte)0x7F,
  98. (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm,
  99. [Values(0b000u, 0b001u, 0b010u, // <UXTB, UXTH, UXTW,
  100. 0b100u, 0b101u, 0b110u)] uint extend, // SXTB, SXTH, SXTW>
  101. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  102. {
  103. uint Opcode = 0x8B200000; // ADD X0, X0, W0, UXTB #0
  104. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  105. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  106. AThreadState ThreadState;
  107. if (Rn != 31)
  108. {
  109. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  110. ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31);
  111. }
  112. else
  113. {
  114. ThreadState = SingleOpcode(Opcode, X31: Xn_SP, X2: Wm);
  115. }
  116. CompareAgainstUnicorn();
  117. }
  118. [Test, Pairwise, Description("ADD <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
  119. public void Add_W_32bit([Values(0u, 31u)] uint Rd,
  120. [Values(1u, 31u)] uint Rn,
  121. [Values(2u, 31u)] uint Rm,
  122. [Values(0x00000000u, 0x7FFFFFFFu,
  123. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
  124. [Values((uint)0x00000000, (uint)0x7FFFFFFF,
  125. (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(RndCnt)] uint Wm,
  126. [Values(0b000u, 0b001u, 0b010u, 0b011u, // <UXTB, UXTH, LSL|UXTW, UXTX,
  127. 0b100u, 0b101u, 0b110u, 0b111u)] uint extend, // SXTB, SXTH, SXTW, SXTX>
  128. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  129. {
  130. uint Opcode = 0x0B200000; // ADD W0, W0, W0, UXTB #0
  131. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  132. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  133. AThreadState ThreadState;
  134. if (Rn != 31)
  135. {
  136. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  137. ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31);
  138. }
  139. else
  140. {
  141. ThreadState = SingleOpcode(Opcode, X31: Wn_WSP, X2: Wm);
  142. }
  143. CompareAgainstUnicorn();
  144. }
  145. [Test, Pairwise, Description("ADD <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
  146. public void Add_H_32bit([Values(0u, 31u)] uint Rd,
  147. [Values(1u, 31u)] uint Rn,
  148. [Values(2u, 31u)] uint Rm,
  149. [Values(0x00000000u, 0x7FFFFFFFu,
  150. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
  151. [Values((ushort)0x0000, (ushort)0x7FFF,
  152. (ushort)0x8000, (ushort)0xFFFF)] [Random(RndCnt)] ushort Wm,
  153. [Values(0b000u, 0b001u, 0b010u, 0b011u, // <UXTB, UXTH, LSL|UXTW, UXTX,
  154. 0b100u, 0b101u, 0b110u, 0b111u)] uint extend, // SXTB, SXTH, SXTW, SXTX>
  155. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  156. {
  157. uint Opcode = 0x0B200000; // ADD W0, W0, W0, UXTB #0
  158. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  159. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  160. AThreadState ThreadState;
  161. if (Rn != 31)
  162. {
  163. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  164. ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31);
  165. }
  166. else
  167. {
  168. ThreadState = SingleOpcode(Opcode, X31: Wn_WSP, X2: Wm);
  169. }
  170. CompareAgainstUnicorn();
  171. }
  172. [Test, Pairwise, Description("ADD <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
  173. public void Add_B_32bit([Values(0u, 31u)] uint Rd,
  174. [Values(1u, 31u)] uint Rn,
  175. [Values(2u, 31u)] uint Rm,
  176. [Values(0x00000000u, 0x7FFFFFFFu,
  177. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
  178. [Values((byte)0x00, (byte)0x7F,
  179. (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm,
  180. [Values(0b000u, 0b001u, 0b010u, 0b011u, // <UXTB, UXTH, LSL|UXTW, UXTX,
  181. 0b100u, 0b101u, 0b110u, 0b111u)] uint extend, // SXTB, SXTH, SXTW, SXTX>
  182. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  183. {
  184. uint Opcode = 0x0B200000; // ADD W0, W0, W0, UXTB #0
  185. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  186. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  187. AThreadState ThreadState;
  188. if (Rn != 31)
  189. {
  190. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  191. ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31);
  192. }
  193. else
  194. {
  195. ThreadState = SingleOpcode(Opcode, X31: Wn_WSP, X2: Wm);
  196. }
  197. CompareAgainstUnicorn();
  198. }
  199. [Test, Pairwise, Description("ADDS <Xd>, <Xn|SP>, <X><m>{, <extend> {#<amount>}}")]
  200. public void Adds_X_64bit([Values(0u, 31u)] uint Rd,
  201. [Values(1u, 31u)] uint Rn,
  202. [Values(2u, 31u)] uint Rm,
  203. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  204. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
  205. [Values((ulong)0x0000000000000000, (ulong)0x7FFFFFFFFFFFFFFF,
  206. (ulong)0x8000000000000000, (ulong)0xFFFFFFFFFFFFFFFF)] [Random(RndCnt)] ulong Xm,
  207. [Values(0b011u, 0b111u)] uint extend, // <LSL|UXTX, SXTX>
  208. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  209. {
  210. uint Opcode = 0xAB206000; // ADDS X0, X0, X0, UXTX #0
  211. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  212. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  213. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Xm, X31: Xn_SP);
  214. CompareAgainstUnicorn();
  215. }
  216. [Test, Pairwise, Description("ADDS <Xd>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
  217. public void Adds_W_64bit([Values(0u, 31u)] uint Rd,
  218. [Values(1u, 31u)] uint Rn,
  219. [Values(2u, 31u)] uint Rm,
  220. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  221. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
  222. [Values((uint)0x00000000, (uint)0x7FFFFFFF,
  223. (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(RndCnt)] uint Wm,
  224. [Values(0b000u, 0b001u, 0b010u, // <UXTB, UXTH, UXTW,
  225. 0b100u, 0b101u, 0b110u)] uint extend, // SXTB, SXTH, SXTW>
  226. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  227. {
  228. uint Opcode = 0xAB200000; // ADDS X0, X0, W0, UXTB #0
  229. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  230. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  231. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: Xn_SP);
  232. CompareAgainstUnicorn();
  233. }
  234. [Test, Pairwise, Description("ADDS <Xd>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
  235. public void Adds_H_64bit([Values(0u, 31u)] uint Rd,
  236. [Values(1u, 31u)] uint Rn,
  237. [Values(2u, 31u)] uint Rm,
  238. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  239. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
  240. [Values((ushort)0x0000, (ushort)0x7FFF,
  241. (ushort)0x8000, (ushort)0xFFFF)] [Random(RndCnt)] ushort Wm,
  242. [Values(0b000u, 0b001u, 0b010u, // <UXTB, UXTH, UXTW,
  243. 0b100u, 0b101u, 0b110u)] uint extend, // SXTB, SXTH, SXTW>
  244. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  245. {
  246. uint Opcode = 0xAB200000; // ADDS X0, X0, W0, UXTB #0
  247. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  248. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  249. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: Xn_SP);
  250. CompareAgainstUnicorn();
  251. }
  252. [Test, Pairwise, Description("ADDS <Xd>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
  253. public void Adds_B_64bit([Values(0u, 31u)] uint Rd,
  254. [Values(1u, 31u)] uint Rn,
  255. [Values(2u, 31u)] uint Rm,
  256. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  257. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
  258. [Values((byte)0x00, (byte)0x7F,
  259. (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm,
  260. [Values(0b000u, 0b001u, 0b010u, // <UXTB, UXTH, UXTW,
  261. 0b100u, 0b101u, 0b110u)] uint extend, // SXTB, SXTH, SXTW>
  262. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  263. {
  264. uint Opcode = 0xAB200000; // ADDS X0, X0, W0, UXTB #0
  265. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  266. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  267. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: Xn_SP);
  268. CompareAgainstUnicorn();
  269. }
  270. [Test, Pairwise, Description("ADDS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
  271. public void Adds_W_32bit([Values(0u, 31u)] uint Rd,
  272. [Values(1u, 31u)] uint Rn,
  273. [Values(2u, 31u)] uint Rm,
  274. [Values(0x00000000u, 0x7FFFFFFFu,
  275. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
  276. [Values((uint)0x00000000, (uint)0x7FFFFFFF,
  277. (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(RndCnt)] uint Wm,
  278. [Values(0b000u, 0b001u, 0b010u, 0b011u, // <UXTB, UXTH, LSL|UXTW, UXTX,
  279. 0b100u, 0b101u, 0b110u, 0b111u)] uint extend, // SXTB, SXTH, SXTW, SXTX>
  280. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  281. {
  282. uint Opcode = 0x2B200000; // ADDS W0, W0, W0, UXTB #0
  283. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  284. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  285. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: Wn_WSP);
  286. CompareAgainstUnicorn();
  287. }
  288. [Test, Pairwise, Description("ADDS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
  289. public void Adds_H_32bit([Values(0u, 31u)] uint Rd,
  290. [Values(1u, 31u)] uint Rn,
  291. [Values(2u, 31u)] uint Rm,
  292. [Values(0x00000000u, 0x7FFFFFFFu,
  293. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
  294. [Values((ushort)0x0000, (ushort)0x7FFF,
  295. (ushort)0x8000, (ushort)0xFFFF)] [Random(RndCnt)] ushort Wm,
  296. [Values(0b000u, 0b001u, 0b010u, 0b011u, // <UXTB, UXTH, LSL|UXTW, UXTX,
  297. 0b100u, 0b101u, 0b110u, 0b111u)] uint extend, // SXTB, SXTH, SXTW, SXTX>
  298. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  299. {
  300. uint Opcode = 0x2B200000; // ADDS W0, W0, W0, UXTB #0
  301. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  302. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  303. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: Wn_WSP);
  304. CompareAgainstUnicorn();
  305. }
  306. [Test, Pairwise, Description("ADDS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
  307. public void Adds_B_32bit([Values(0u, 31u)] uint Rd,
  308. [Values(1u, 31u)] uint Rn,
  309. [Values(2u, 31u)] uint Rm,
  310. [Values(0x00000000u, 0x7FFFFFFFu,
  311. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
  312. [Values((byte)0x00, (byte)0x7F,
  313. (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm,
  314. [Values(0b000u, 0b001u, 0b010u, 0b011u, // <UXTB, UXTH, LSL|UXTW, UXTX,
  315. 0b100u, 0b101u, 0b110u, 0b111u)] uint extend, // SXTB, SXTH, SXTW, SXTX>
  316. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  317. {
  318. uint Opcode = 0x2B200000; // ADDS W0, W0, W0, UXTB #0
  319. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  320. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  321. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: Wn_WSP);
  322. CompareAgainstUnicorn();
  323. }
  324. [Test, Pairwise, Description("SUB <Xd|SP>, <Xn|SP>, <X><m>{, <extend> {#<amount>}}")]
  325. public void Sub_X_64bit([Values(0u, 31u)] uint Rd,
  326. [Values(1u, 31u)] uint Rn,
  327. [Values(2u, 31u)] uint Rm,
  328. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  329. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
  330. [Values((ulong)0x0000000000000000, (ulong)0x7FFFFFFFFFFFFFFF,
  331. (ulong)0x8000000000000000, (ulong)0xFFFFFFFFFFFFFFFF)] [Random(RndCnt)] ulong Xm,
  332. [Values(0b011u, 0b111u)] uint extend, // <LSL|UXTX, SXTX>
  333. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  334. {
  335. uint Opcode = 0xCB206000; // SUB X0, X0, X0, UXTX #0
  336. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  337. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  338. AThreadState ThreadState;
  339. if (Rn != 31)
  340. {
  341. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  342. ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Xm, X31: _X31);
  343. }
  344. else
  345. {
  346. ThreadState = SingleOpcode(Opcode, X31: Xn_SP, X2: Xm);
  347. }
  348. CompareAgainstUnicorn();
  349. }
  350. [Test, Pairwise, Description("SUB <Xd|SP>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
  351. public void Sub_W_64bit([Values(0u, 31u)] uint Rd,
  352. [Values(1u, 31u)] uint Rn,
  353. [Values(2u, 31u)] uint Rm,
  354. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  355. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
  356. [Values((uint)0x00000000, (uint)0x7FFFFFFF,
  357. (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(RndCnt)] uint Wm,
  358. [Values(0b000u, 0b001u, 0b010u, // <UXTB, UXTH, UXTW,
  359. 0b100u, 0b101u, 0b110u)] uint extend, // SXTB, SXTH, SXTW>
  360. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  361. {
  362. uint Opcode = 0xCB200000; // SUB X0, X0, W0, UXTB #0
  363. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  364. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  365. AThreadState ThreadState;
  366. if (Rn != 31)
  367. {
  368. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  369. ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31);
  370. }
  371. else
  372. {
  373. ThreadState = SingleOpcode(Opcode, X31: Xn_SP, X2: Wm);
  374. }
  375. CompareAgainstUnicorn();
  376. }
  377. [Test, Pairwise, Description("SUB <Xd|SP>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
  378. public void Sub_H_64bit([Values(0u, 31u)] uint Rd,
  379. [Values(1u, 31u)] uint Rn,
  380. [Values(2u, 31u)] uint Rm,
  381. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  382. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
  383. [Values((ushort)0x0000, (ushort)0x7FFF,
  384. (ushort)0x8000, (ushort)0xFFFF)] [Random(RndCnt)] ushort Wm,
  385. [Values(0b000u, 0b001u, 0b010u, // <UXTB, UXTH, UXTW,
  386. 0b100u, 0b101u, 0b110u)] uint extend, // SXTB, SXTH, SXTW>
  387. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  388. {
  389. uint Opcode = 0xCB200000; // SUB X0, X0, W0, UXTB #0
  390. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  391. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  392. AThreadState ThreadState;
  393. if (Rn != 31)
  394. {
  395. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  396. ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31);
  397. }
  398. else
  399. {
  400. ThreadState = SingleOpcode(Opcode, X31: Xn_SP, X2: Wm);
  401. }
  402. CompareAgainstUnicorn();
  403. }
  404. [Test, Pairwise, Description("SUB <Xd|SP>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
  405. public void Sub_B_64bit([Values(0u, 31u)] uint Rd,
  406. [Values(1u, 31u)] uint Rn,
  407. [Values(2u, 31u)] uint Rm,
  408. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  409. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
  410. [Values((byte)0x00, (byte)0x7F,
  411. (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm,
  412. [Values(0b000u, 0b001u, 0b010u, // <UXTB, UXTH, UXTW,
  413. 0b100u, 0b101u, 0b110u)] uint extend, // SXTB, SXTH, SXTW>
  414. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  415. {
  416. uint Opcode = 0xCB200000; // SUB X0, X0, W0, UXTB #0
  417. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  418. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  419. AThreadState ThreadState;
  420. if (Rn != 31)
  421. {
  422. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  423. ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31);
  424. }
  425. else
  426. {
  427. ThreadState = SingleOpcode(Opcode, X31: Xn_SP, X2: Wm);
  428. }
  429. CompareAgainstUnicorn();
  430. }
  431. [Test, Pairwise, Description("SUB <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
  432. public void Sub_W_32bit([Values(0u, 31u)] uint Rd,
  433. [Values(1u, 31u)] uint Rn,
  434. [Values(2u, 31u)] uint Rm,
  435. [Values(0x00000000u, 0x7FFFFFFFu,
  436. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
  437. [Values((uint)0x00000000, (uint)0x7FFFFFFF,
  438. (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(RndCnt)] uint Wm,
  439. [Values(0b000u, 0b001u, 0b010u, 0b011u, // <UXTB, UXTH, LSL|UXTW, UXTX,
  440. 0b100u, 0b101u, 0b110u, 0b111u)] uint extend, // SXTB, SXTH, SXTW, SXTX>
  441. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  442. {
  443. uint Opcode = 0x4B200000; // SUB W0, W0, W0, UXTB #0
  444. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  445. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  446. AThreadState ThreadState;
  447. if (Rn != 31)
  448. {
  449. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  450. ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31);
  451. }
  452. else
  453. {
  454. ThreadState = SingleOpcode(Opcode, X31: Wn_WSP, X2: Wm);
  455. }
  456. CompareAgainstUnicorn();
  457. }
  458. [Test, Pairwise, Description("SUB <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
  459. public void Sub_H_32bit([Values(0u, 31u)] uint Rd,
  460. [Values(1u, 31u)] uint Rn,
  461. [Values(2u, 31u)] uint Rm,
  462. [Values(0x00000000u, 0x7FFFFFFFu,
  463. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
  464. [Values((ushort)0x0000, (ushort)0x7FFF,
  465. (ushort)0x8000, (ushort)0xFFFF)] [Random(RndCnt)] ushort Wm,
  466. [Values(0b000u, 0b001u, 0b010u, 0b011u, // <UXTB, UXTH, LSL|UXTW, UXTX,
  467. 0b100u, 0b101u, 0b110u, 0b111u)] uint extend, // SXTB, SXTH, SXTW, SXTX>
  468. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  469. {
  470. uint Opcode = 0x4B200000; // SUB W0, W0, W0, UXTB #0
  471. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  472. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  473. AThreadState ThreadState;
  474. if (Rn != 31)
  475. {
  476. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  477. ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31);
  478. }
  479. else
  480. {
  481. ThreadState = SingleOpcode(Opcode, X31: Wn_WSP, X2: Wm);
  482. }
  483. CompareAgainstUnicorn();
  484. }
  485. [Test, Pairwise, Description("SUB <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
  486. public void Sub_B_32bit([Values(0u, 31u)] uint Rd,
  487. [Values(1u, 31u)] uint Rn,
  488. [Values(2u, 31u)] uint Rm,
  489. [Values(0x00000000u, 0x7FFFFFFFu,
  490. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
  491. [Values((byte)0x00, (byte)0x7F,
  492. (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm,
  493. [Values(0b000u, 0b001u, 0b010u, 0b011u, // <UXTB, UXTH, LSL|UXTW, UXTX,
  494. 0b100u, 0b101u, 0b110u, 0b111u)] uint extend, // SXTB, SXTH, SXTW, SXTX>
  495. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  496. {
  497. uint Opcode = 0x4B200000; // SUB W0, W0, W0, UXTB #0
  498. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  499. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  500. AThreadState ThreadState;
  501. if (Rn != 31)
  502. {
  503. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  504. ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31);
  505. }
  506. else
  507. {
  508. ThreadState = SingleOpcode(Opcode, X31: Wn_WSP, X2: Wm);
  509. }
  510. CompareAgainstUnicorn();
  511. }
  512. [Test, Pairwise, Description("SUBS <Xd>, <Xn|SP>, <X><m>{, <extend> {#<amount>}}")]
  513. public void Subs_X_64bit([Values(0u, 31u)] uint Rd,
  514. [Values(1u, 31u)] uint Rn,
  515. [Values(2u, 31u)] uint Rm,
  516. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  517. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
  518. [Values((ulong)0x0000000000000000, (ulong)0x7FFFFFFFFFFFFFFF,
  519. (ulong)0x8000000000000000, (ulong)0xFFFFFFFFFFFFFFFF)] [Random(RndCnt)] ulong Xm,
  520. [Values(0b011u, 0b111u)] uint extend, // <LSL|UXTX, SXTX>
  521. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  522. {
  523. uint Opcode = 0xEB206000; // SUBS X0, X0, X0, UXTX #0
  524. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  525. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  526. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Xm, X31: Xn_SP);
  527. CompareAgainstUnicorn();
  528. }
  529. [Test, Pairwise, Description("SUBS <Xd>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
  530. public void Subs_W_64bit([Values(0u, 31u)] uint Rd,
  531. [Values(1u, 31u)] uint Rn,
  532. [Values(2u, 31u)] uint Rm,
  533. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  534. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
  535. [Values((uint)0x00000000, (uint)0x7FFFFFFF,
  536. (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(RndCnt)] uint Wm,
  537. [Values(0b000u, 0b001u, 0b010u, // <UXTB, UXTH, UXTW,
  538. 0b100u, 0b101u, 0b110u)] uint extend, // SXTB, SXTH, SXTW>
  539. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  540. {
  541. uint Opcode = 0xEB200000; // SUBS X0, X0, W0, UXTB #0
  542. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  543. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  544. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: Xn_SP);
  545. CompareAgainstUnicorn();
  546. }
  547. [Test, Pairwise, Description("SUBS <Xd>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
  548. public void Subs_H_64bit([Values(0u, 31u)] uint Rd,
  549. [Values(1u, 31u)] uint Rn,
  550. [Values(2u, 31u)] uint Rm,
  551. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  552. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
  553. [Values((ushort)0x0000, (ushort)0x7FFF,
  554. (ushort)0x8000, (ushort)0xFFFF)] [Random(RndCnt)] ushort Wm,
  555. [Values(0b000u, 0b001u, 0b010u, // <UXTB, UXTH, UXTW,
  556. 0b100u, 0b101u, 0b110u)] uint extend, // SXTB, SXTH, SXTW>
  557. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  558. {
  559. uint Opcode = 0xEB200000; // SUBS X0, X0, W0, UXTB #0
  560. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  561. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  562. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: Xn_SP);
  563. CompareAgainstUnicorn();
  564. }
  565. [Test, Pairwise, Description("SUBS <Xd>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
  566. public void Subs_B_64bit([Values(0u, 31u)] uint Rd,
  567. [Values(1u, 31u)] uint Rn,
  568. [Values(2u, 31u)] uint Rm,
  569. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  570. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
  571. [Values((byte)0x00, (byte)0x7F,
  572. (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm,
  573. [Values(0b000u, 0b001u, 0b010u, // <UXTB, UXTH, UXTW,
  574. 0b100u, 0b101u, 0b110u)] uint extend, // SXTB, SXTH, SXTW>
  575. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  576. {
  577. uint Opcode = 0xEB200000; // SUBS X0, X0, W0, UXTB #0
  578. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  579. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  580. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: Xn_SP);
  581. CompareAgainstUnicorn();
  582. }
  583. [Test, Pairwise, Description("SUBS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
  584. public void Subs_W_32bit([Values(0u, 31u)] uint Rd,
  585. [Values(1u, 31u)] uint Rn,
  586. [Values(2u, 31u)] uint Rm,
  587. [Values(0x00000000u, 0x7FFFFFFFu,
  588. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
  589. [Values((uint)0x00000000, (uint)0x7FFFFFFF,
  590. (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(RndCnt)] uint Wm,
  591. [Values(0b000u, 0b001u, 0b010u, 0b011u, // <UXTB, UXTH, LSL|UXTW, UXTX,
  592. 0b100u, 0b101u, 0b110u, 0b111u)] uint extend, // SXTB, SXTH, SXTW, SXTX>
  593. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  594. {
  595. uint Opcode = 0x6B200000; // SUBS W0, W0, W0, UXTB #0
  596. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  597. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  598. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: Wn_WSP);
  599. CompareAgainstUnicorn();
  600. }
  601. [Test, Pairwise, Description("SUBS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
  602. public void Subs_H_32bit([Values(0u, 31u)] uint Rd,
  603. [Values(1u, 31u)] uint Rn,
  604. [Values(2u, 31u)] uint Rm,
  605. [Values(0x00000000u, 0x7FFFFFFFu,
  606. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
  607. [Values((ushort)0x0000, (ushort)0x7FFF,
  608. (ushort)0x8000, (ushort)0xFFFF)] [Random(RndCnt)] ushort Wm,
  609. [Values(0b000u, 0b001u, 0b010u, 0b011u, // <UXTB, UXTH, LSL|UXTW, UXTX,
  610. 0b100u, 0b101u, 0b110u, 0b111u)] uint extend, // SXTB, SXTH, SXTW, SXTX>
  611. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  612. {
  613. uint Opcode = 0x6B200000; // SUBS W0, W0, W0, UXTB #0
  614. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  615. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  616. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: Wn_WSP);
  617. CompareAgainstUnicorn();
  618. }
  619. [Test, Pairwise, Description("SUBS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
  620. public void Subs_B_32bit([Values(0u, 31u)] uint Rd,
  621. [Values(1u, 31u)] uint Rn,
  622. [Values(2u, 31u)] uint Rm,
  623. [Values(0x00000000u, 0x7FFFFFFFu,
  624. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
  625. [Values((byte)0x00, (byte)0x7F,
  626. (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm,
  627. [Values(0b000u, 0b001u, 0b010u, 0b011u, // <UXTB, UXTH, LSL|UXTW, UXTX,
  628. 0b100u, 0b101u, 0b110u, 0b111u)] uint extend, // SXTB, SXTH, SXTW, SXTX>
  629. [Values(0u, 1u, 2u, 3u, 4u)] uint amount)
  630. {
  631. uint Opcode = 0x6B200000; // SUBS W0, W0, W0, UXTB #0
  632. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  633. Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10);
  634. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: Wn_WSP);
  635. CompareAgainstUnicorn();
  636. }
  637. #endif
  638. }
  639. }