CpuTestAluRx.cs 36 KB

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