SMEInstrFormats.td 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. //=-- SMEInstrFormats.td - AArch64 SME Instruction classes -*- tablegen -*--=//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // AArch64 Scalable Matrix Extension (SME) Instruction Class Definitions.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. //===----------------------------------------------------------------------===//
  13. // SME Outer Products
  14. //===----------------------------------------------------------------------===//
  15. class sme_fp_outer_product_inst<bit S, bit sz, MatrixTileOperand za_ty,
  16. ZPRRegOp zpr_ty, string mnemonic>
  17. : I<(outs za_ty:$ZAda),
  18. (ins PPR3bAny:$Pn, PPR3bAny:$Pm, zpr_ty:$Zn, zpr_ty:$Zm),
  19. mnemonic, "\t$ZAda, $Pn/m, $Pm/m, $Zn, $Zm",
  20. "", []>,
  21. Sched<[]> {
  22. bits<5> Zm;
  23. bits<3> Pm;
  24. bits<3> Pn;
  25. bits<5> Zn;
  26. let Inst{31-23} = 0b100000001;
  27. let Inst{22} = sz;
  28. let Inst{21} = 0b0;
  29. let Inst{20-16} = Zm;
  30. let Inst{15-13} = Pm;
  31. let Inst{12-10} = Pn;
  32. let Inst{9-5} = Zn;
  33. let Inst{4} = S;
  34. let Inst{3} = 0b0;
  35. }
  36. class sme_outer_product_fp32<bit S, string mnemonic>
  37. : sme_fp_outer_product_inst<S, 0b0, TileOp32, ZPR32, mnemonic> {
  38. bits<2> ZAda;
  39. let Inst{1-0} = ZAda;
  40. let Inst{2} = 0b0;
  41. }
  42. class sme_outer_product_fp64<bit S, string mnemonic>
  43. : sme_fp_outer_product_inst<S, 0b1, TileOp64, ZPR64, mnemonic> {
  44. bits<3> ZAda;
  45. let Inst{2-0} = ZAda;
  46. }
  47. class sme_int_outer_product_inst<bit u0, bit u1, bit S, bit sz,
  48. MatrixTileOperand za_ty, ZPRRegOp zpr_ty,
  49. string mnemonic>
  50. : I<(outs za_ty:$ZAda),
  51. (ins PPR3bAny:$Pn, PPR3bAny:$Pm, zpr_ty:$Zn, zpr_ty:$Zm),
  52. mnemonic, "\t$ZAda, $Pn/m, $Pm/m, $Zn, $Zm",
  53. "", []>,
  54. Sched<[]> {
  55. bits<5> Zm;
  56. bits<3> Pm;
  57. bits<3> Pn;
  58. bits<5> Zn;
  59. let Inst{31-25} = 0b1010000;
  60. let Inst{24} = u0;
  61. let Inst{23} = 0b1;
  62. let Inst{22} = sz;
  63. let Inst{21} = u1;
  64. let Inst{20-16} = Zm;
  65. let Inst{15-13} = Pm;
  66. let Inst{12-10} = Pn;
  67. let Inst{9-5} = Zn;
  68. let Inst{4} = S;
  69. let Inst{3} = 0b0;
  70. }
  71. class sme_int_outer_product_i32<bits<3> opc, string mnemonic>
  72. : sme_int_outer_product_inst<opc{2}, opc{1}, opc{0}, 0b0, TileOp32, ZPR8,
  73. mnemonic> {
  74. bits<2> ZAda;
  75. let Inst{1-0} = ZAda;
  76. let Inst{2} = 0b0;
  77. }
  78. class sme_int_outer_product_i64<bits<3> opc, string mnemonic>
  79. : sme_int_outer_product_inst<opc{2}, opc{1}, opc{0}, 0b1, TileOp64, ZPR16,
  80. mnemonic> {
  81. bits<3> ZAda;
  82. let Inst{2-0} = ZAda;
  83. }
  84. class sme_outer_product_widening_inst<bit op, bit S, string mnemonic>
  85. : I<(outs TileOp32:$ZAda),
  86. (ins PPR3bAny:$Pn, PPR3bAny:$Pm, ZPR16:$Zn, ZPR16:$Zm),
  87. mnemonic, "\t$ZAda, $Pn/m, $Pm/m, $Zn, $Zm",
  88. "", []>,
  89. Sched<[]> {
  90. bits<5> Zm;
  91. bits<3> Pm;
  92. bits<3> Pn;
  93. bits<5> Zn;
  94. bits<2> ZAda;
  95. let Inst{31-22} = 0b1000000110;
  96. let Inst{21} = op;
  97. let Inst{20-16} = Zm;
  98. let Inst{15-13} = Pm;
  99. let Inst{12-10} = Pn;
  100. let Inst{9-5} = Zn;
  101. let Inst{4} = S;
  102. let Inst{3-2} = 0b00;
  103. let Inst{1-0} = ZAda;
  104. }
  105. multiclass sme_bf16_outer_product<bit S, string mnemonic> {
  106. def : sme_outer_product_widening_inst<0b0, S, mnemonic>;
  107. }
  108. multiclass sme_f16_outer_product<bit S, string mnemonic> {
  109. def : sme_outer_product_widening_inst<0b1, S, mnemonic>;
  110. }
  111. //===----------------------------------------------------------------------===//
  112. // SME Add Vector to Tile
  113. //===----------------------------------------------------------------------===//
  114. class sme_add_vector_to_tile_inst<bit op, bit V, MatrixTileOperand tile_ty,
  115. ZPRRegOp zpr_ty, string mnemonic>
  116. : I<(outs tile_ty:$ZAda),
  117. (ins PPR3bAny:$Pn, PPR3bAny:$Pm, zpr_ty:$Zn),
  118. mnemonic, "\t$ZAda, $Pn/m, $Pm/m, $Zn",
  119. "", []>, Sched<[]> {
  120. bits<3> Pm;
  121. bits<3> Pn;
  122. bits<5> Zn;
  123. let Inst{31-23} = 0b110000001;
  124. let Inst{22} = op;
  125. let Inst{21-17} = 0b01000;
  126. let Inst{16} = V;
  127. let Inst{15-13} = Pm;
  128. let Inst{12-10} = Pn;
  129. let Inst{9-5} = Zn;
  130. let Inst{4-3} = 0b00;
  131. }
  132. class sme_add_vector_to_tile_u32<bit V, string mnemonic>
  133. : sme_add_vector_to_tile_inst<0b0, V, TileOp32, ZPR32, mnemonic> {
  134. bits<2> ZAda;
  135. let Inst{2} = 0b0;
  136. let Inst{1-0} = ZAda;
  137. }
  138. class sme_add_vector_to_tile_u64<bit V, string mnemonic>
  139. : sme_add_vector_to_tile_inst<0b1, V, TileOp64, ZPR64, mnemonic> {
  140. bits<3> ZAda;
  141. let Inst{2-0} = ZAda;
  142. }
  143. //===----------------------------------------------------------------------===//
  144. // SME Contiguous Loads
  145. //===----------------------------------------------------------------------===//
  146. class sme_mem_ld_ss_base<bit Q, bit V, bits<2> msz, dag outs, dag ins,
  147. string mnemonic, string argstr>
  148. : I<outs, ins, mnemonic, argstr, "", []>, Sched<[]> {
  149. bits<5> Rm;
  150. bits<2> Rv;
  151. bits<3> Pg;
  152. bits<5> Rn;
  153. let Inst{31-25} = 0b1110000;
  154. let Inst{24} = Q;
  155. let Inst{23-22} = msz;
  156. let Inst{21} = 0b0;
  157. let Inst{20-16} = Rm;
  158. let Inst{15} = V;
  159. let Inst{14-13} = Rv;
  160. let Inst{12-10} = Pg;
  161. let Inst{9-5} = Rn;
  162. let Inst{4} = 0b0;
  163. let mayLoad = 1;
  164. }
  165. class sme_mem_ld_ss_inst<bit Q, bits<2> msz, string mnemonic,
  166. MatrixTileVectorOperand tile_ty, bit is_col,
  167. Operand imm_ty, RegisterOperand gpr_ty>
  168. : sme_mem_ld_ss_base<
  169. Q, is_col, msz, (outs tile_ty:$ZAt),
  170. (ins MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, GPR64sp:$Rn,
  171. gpr_ty:$Rm),
  172. mnemonic, "\t\\{$ZAt[$Rv, $imm]\\}, $Pg/z, [$Rn, $Rm]">;
  173. multiclass sme_mem_ss_aliases_base<string mnemonic, Instruction inst,
  174. MatrixTileVectorOperand tile_ty,
  175. Operand imm_ty, RegisterOperand gpr_ty,
  176. string pg_suffix=""> {
  177. def : InstAlias<mnemonic # "\t$ZAt[$Rv, $imm], $Pg" # pg_suffix # ", [$Rn, $Rm]",
  178. (inst tile_ty:$ZAt, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, GPR64sp:$Rn, gpr_ty:$Rm), 0>;
  179. // Default XZR offset aliases
  180. def : InstAlias<mnemonic # "\t\\{$ZAt[$Rv, $imm]\\}, $Pg" # pg_suffix # ", [$Rn]",
  181. (inst tile_ty:$ZAt, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 1>;
  182. def : InstAlias<mnemonic # "\t$ZAt[$Rv, $imm], $Pg" # pg_suffix # ", [$Rn]",
  183. (inst tile_ty:$ZAt, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 0>;
  184. }
  185. multiclass sme_mem_ss_aliases<string mnemonic, string inst, bit is_col,
  186. string pg_suffix=""> {
  187. defm : sme_mem_ss_aliases_base<mnemonic # "b", !cast<Instruction>(inst # _B),
  188. !if(is_col, TileVectorOpV8, TileVectorOpH8),
  189. sme_elm_idx0_15, GPR64shifted8, pg_suffix>;
  190. defm : sme_mem_ss_aliases_base<mnemonic # "h", !cast<Instruction>(inst # _H),
  191. !if(is_col, TileVectorOpV16, TileVectorOpH16),
  192. sme_elm_idx0_7, GPR64shifted16, pg_suffix>;
  193. defm : sme_mem_ss_aliases_base<mnemonic # "w", !cast<Instruction>(inst # _S),
  194. !if(is_col, TileVectorOpV32, TileVectorOpH32),
  195. sme_elm_idx0_3, GPR64shifted32, pg_suffix>;
  196. defm : sme_mem_ss_aliases_base<mnemonic # "d", !cast<Instruction>(inst # _D),
  197. !if(is_col, TileVectorOpV64, TileVectorOpH64),
  198. sme_elm_idx0_1, GPR64shifted64, pg_suffix>;
  199. defm : sme_mem_ss_aliases_base<mnemonic # "q", !cast<Instruction>(inst # _Q),
  200. !if(is_col, TileVectorOpV128, TileVectorOpH128),
  201. sme_elm_idx0_0, GPR64shifted128, pg_suffix>;
  202. }
  203. multiclass sme_mem_ld_ss_aliases<string inst, bit is_col> {
  204. defm NAME : sme_mem_ss_aliases<"ld1", inst, is_col, "/z">;
  205. }
  206. multiclass sme_mem_ld_v_ss<string mnemonic, bit is_col> {
  207. def _B : sme_mem_ld_ss_inst<0b0, 0b00, mnemonic # "b",
  208. !if(is_col, TileVectorOpV8, TileVectorOpH8),
  209. is_col, sme_elm_idx0_15, GPR64shifted8> {
  210. bits<4> imm;
  211. let Inst{3-0} = imm;
  212. }
  213. def _H : sme_mem_ld_ss_inst<0b0, 0b01, mnemonic # "h",
  214. !if(is_col, TileVectorOpV16, TileVectorOpH16),
  215. is_col, sme_elm_idx0_7, GPR64shifted16> {
  216. bits<1> ZAt;
  217. bits<3> imm;
  218. let Inst{3} = ZAt;
  219. let Inst{2-0} = imm;
  220. }
  221. def _S : sme_mem_ld_ss_inst<0b0, 0b10, mnemonic # "w",
  222. !if(is_col, TileVectorOpV32, TileVectorOpH32),
  223. is_col, sme_elm_idx0_3, GPR64shifted32> {
  224. bits<2> ZAt;
  225. bits<2> imm;
  226. let Inst{3-2} = ZAt;
  227. let Inst{1-0} = imm;
  228. }
  229. def _D : sme_mem_ld_ss_inst<0b0, 0b11, mnemonic # "d",
  230. !if(is_col, TileVectorOpV64, TileVectorOpH64),
  231. is_col, sme_elm_idx0_1, GPR64shifted64> {
  232. bits<3> ZAt;
  233. bits<1> imm;
  234. let Inst{3-1} = ZAt;
  235. let Inst{0} = imm;
  236. }
  237. def _Q : sme_mem_ld_ss_inst<0b1, 0b11, mnemonic # "q",
  238. !if(is_col, TileVectorOpV128, TileVectorOpH128),
  239. is_col, sme_elm_idx0_0, GPR64shifted128> {
  240. bits<4> ZAt;
  241. let Inst{3-0} = ZAt;
  242. }
  243. defm : sme_mem_ld_ss_aliases<NAME, is_col>;
  244. }
  245. multiclass sme_mem_ld_ss<string mnemonic> {
  246. defm _H : sme_mem_ld_v_ss<mnemonic, /*is_col=*/0b0>;
  247. defm _V : sme_mem_ld_v_ss<mnemonic, /*is_col=*/0b1>;
  248. }
  249. //===----------------------------------------------------------------------===//
  250. // SME Contiguous Stores
  251. //===----------------------------------------------------------------------===//
  252. class sme_mem_st_ss_base<bit Q, bit V, bits<2> msz, dag ins,
  253. string mnemonic, string argstr>
  254. : I<(outs), ins, mnemonic, argstr, "", []>, Sched<[]> {
  255. bits<5> Rm;
  256. bits<2> Rv;
  257. bits<3> Pg;
  258. bits<5> Rn;
  259. let Inst{31-25} = 0b1110000;
  260. let Inst{24} = Q;
  261. let Inst{23-22} = msz;
  262. let Inst{21} = 0b1;
  263. let Inst{20-16} = Rm;
  264. let Inst{15} = V;
  265. let Inst{14-13} = Rv;
  266. let Inst{12-10} = Pg;
  267. let Inst{9-5} = Rn;
  268. let Inst{4} = 0b0;
  269. let mayStore = 1;
  270. let hasSideEffects = 1;
  271. }
  272. class sme_mem_st_ss_inst<bit Q, bits<2> msz, string mnemonic,
  273. MatrixTileVectorOperand tile_ty, bit is_col,
  274. Operand imm_ty, RegisterOperand gpr_ty>
  275. : sme_mem_st_ss_base<
  276. Q, is_col, msz,
  277. (ins tile_ty:$ZAt, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg,
  278. GPR64sp:$Rn, gpr_ty:$Rm),
  279. mnemonic, "\t\\{$ZAt[$Rv, $imm]\\}, $Pg, [$Rn, $Rm]">;
  280. multiclass sme_mem_st_ss_aliases<string inst, bit is_col> {
  281. defm NAME : sme_mem_ss_aliases<"st1", inst, is_col>;
  282. }
  283. multiclass sme_mem_st_v_ss<string mnemonic, bit is_col> {
  284. def _B : sme_mem_st_ss_inst<0b0, 0b00, mnemonic # "b",
  285. !if(is_col, TileVectorOpV8, TileVectorOpH8),
  286. is_col, sme_elm_idx0_15, GPR64shifted8> {
  287. bits<4> imm;
  288. let Inst{3-0} = imm;
  289. }
  290. def _H : sme_mem_st_ss_inst<0b0, 0b01, mnemonic # "h",
  291. !if(is_col, TileVectorOpV16, TileVectorOpH16),
  292. is_col, sme_elm_idx0_7, GPR64shifted16> {
  293. bits<1> ZAt;
  294. bits<3> imm;
  295. let Inst{3} = ZAt;
  296. let Inst{2-0} = imm;
  297. }
  298. def _S : sme_mem_st_ss_inst<0b0, 0b10, mnemonic # "w",
  299. !if(is_col, TileVectorOpV32, TileVectorOpH32),
  300. is_col, sme_elm_idx0_3, GPR64shifted32> {
  301. bits<2> ZAt;
  302. bits<2> imm;
  303. let Inst{3-2} = ZAt;
  304. let Inst{1-0} = imm;
  305. }
  306. def _D : sme_mem_st_ss_inst<0b0, 0b11, mnemonic # "d",
  307. !if(is_col, TileVectorOpV64, TileVectorOpH64),
  308. is_col, sme_elm_idx0_1, GPR64shifted64> {
  309. bits<3> ZAt;
  310. bits<1> imm;
  311. let Inst{3-1} = ZAt;
  312. let Inst{0} = imm;
  313. }
  314. def _Q : sme_mem_st_ss_inst<0b1, 0b11, mnemonic # "q",
  315. !if(is_col, TileVectorOpV128, TileVectorOpH128),
  316. is_col, sme_elm_idx0_0, GPR64shifted128> {
  317. bits<4> ZAt;
  318. let Inst{3-0} = ZAt;
  319. }
  320. defm : sme_mem_st_ss_aliases<NAME, is_col>;
  321. }
  322. multiclass sme_mem_st_ss<string mnemonic> {
  323. defm _H : sme_mem_st_v_ss<mnemonic, /*is_col=*/0b0>;
  324. defm _V : sme_mem_st_v_ss<mnemonic, /*is_col=*/0b1>;
  325. }
  326. //===----------------------------------------------------------------------===//
  327. // SME Save and Restore Array
  328. //===----------------------------------------------------------------------===//
  329. class sme_spill_fill_inst<bit isStore, dag outs, dag ins, string opcodestr>
  330. : I<outs, ins, opcodestr, "\t$ZAt[$Rv, $imm4], [$Rn, $offset, mul vl]", "",
  331. []>,
  332. Sched<[]> {
  333. bits<2> Rv;
  334. bits<5> Rn;
  335. bits<4> imm4;
  336. let Inst{31-22} = 0b1110000100;
  337. let Inst{21} = isStore;
  338. let Inst{20-15} = 0b000000;
  339. let Inst{14-13} = Rv;
  340. let Inst{12-10} = 0b000;
  341. let Inst{9-5} = Rn;
  342. let Inst{4} = 0b0;
  343. let Inst{3-0} = imm4;
  344. let mayLoad = !not(isStore);
  345. let mayStore = isStore;
  346. }
  347. multiclass sme_spill_fill<bit isStore, dag outs, dag ins, string opcodestr> {
  348. def NAME : sme_spill_fill_inst<isStore, outs, ins, opcodestr>;
  349. def : InstAlias<opcodestr # "\t$ZAt[$Rv, $imm4], [$Rn]",
  350. (!cast<Instruction>(NAME) MatrixOp:$ZAt,
  351. MatrixIndexGPR32Op12_15:$Rv, sme_elm_idx0_15:$imm4, GPR64sp:$Rn, 0), 1>;
  352. }
  353. multiclass sme_spill<string opcodestr> {
  354. defm NAME : sme_spill_fill<0b1, (outs),
  355. (ins MatrixOp:$ZAt, MatrixIndexGPR32Op12_15:$Rv,
  356. sme_elm_idx0_15:$imm4, GPR64sp:$Rn,
  357. imm0_15:$offset),
  358. opcodestr>;
  359. }
  360. multiclass sme_fill<string opcodestr> {
  361. defm NAME : sme_spill_fill<0b0, (outs MatrixOp:$ZAt),
  362. (ins MatrixIndexGPR32Op12_15:$Rv,
  363. sme_elm_idx0_15:$imm4, GPR64sp:$Rn,
  364. imm0_15:$offset),
  365. opcodestr>;
  366. }
  367. //===----------------------------------------------------------------------===//
  368. // Move instructions
  369. //===----------------------------------------------------------------------===//
  370. class sme_vector_to_tile_base<bit Q, bit V, bits<2> sz, dag outs, dag ins,
  371. string mnemonic, string argstr>
  372. : I<outs, ins, mnemonic, argstr, "", []>, Sched<[]> {
  373. bits<2> Rv;
  374. bits<3> Pg;
  375. bits<5> Zn;
  376. let Inst{31-24} = 0b11000000;
  377. let Inst{23-22} = sz;
  378. let Inst{21-17} = 0b00000;
  379. let Inst{16} = Q;
  380. let Inst{15} = V;
  381. let Inst{14-13} = Rv;
  382. let Inst{12-10} = Pg;
  383. let Inst{9-5} = Zn;
  384. let Inst{4} = 0b0;
  385. }
  386. class sme_vector_to_tile_inst<bit Q, bits<2> sz, MatrixTileVectorOperand tile_ty,
  387. bit is_col, Operand imm_ty, ZPRRegOp zpr_ty,
  388. string mnemonic>
  389. : sme_vector_to_tile_base<Q, is_col, sz, (outs tile_ty:$ZAd),
  390. (ins MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, zpr_ty:$Zn),
  391. mnemonic, "\t$ZAd[$Rv, $imm], $Pg/m, $Zn">;
  392. multiclass sme_vector_to_tile_aliases<Instruction inst,
  393. MatrixTileVectorOperand tile_ty,
  394. ZPRRegOp zpr_ty, Operand imm_ty> {
  395. def : InstAlias<"mov\t$ZAd[$Rv, $imm], $Pg/m, $Zn",
  396. (inst tile_ty:$ZAd, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, zpr_ty:$Zn), 1>;
  397. }
  398. multiclass sme_vector_v_to_tile<string mnemonic, bit is_col> {
  399. def _B : sme_vector_to_tile_inst<0b0, 0b00, !if(is_col, TileVectorOpV8,
  400. TileVectorOpH8),
  401. is_col, sme_elm_idx0_15, ZPR8, mnemonic> {
  402. bits<4> imm;
  403. let Inst{3-0} = imm;
  404. }
  405. def _H : sme_vector_to_tile_inst<0b0, 0b01, !if(is_col, TileVectorOpV16,
  406. TileVectorOpH16),
  407. is_col, sme_elm_idx0_7, ZPR16, mnemonic> {
  408. bits<1> ZAd;
  409. bits<3> imm;
  410. let Inst{3} = ZAd;
  411. let Inst{2-0} = imm;
  412. }
  413. def _S : sme_vector_to_tile_inst<0b0, 0b10, !if(is_col, TileVectorOpV32,
  414. TileVectorOpH32),
  415. is_col, sme_elm_idx0_3, ZPR32, mnemonic> {
  416. bits<2> ZAd;
  417. bits<2> imm;
  418. let Inst{3-2} = ZAd;
  419. let Inst{1-0} = imm;
  420. }
  421. def _D : sme_vector_to_tile_inst<0b0, 0b11, !if(is_col, TileVectorOpV64,
  422. TileVectorOpH64),
  423. is_col, sme_elm_idx0_1, ZPR64, mnemonic> {
  424. bits<3> ZAd;
  425. bits<1> imm;
  426. let Inst{3-1} = ZAd;
  427. let Inst{0} = imm;
  428. }
  429. def _Q : sme_vector_to_tile_inst<0b1, 0b11, !if(is_col, TileVectorOpV128,
  430. TileVectorOpH128),
  431. is_col, sme_elm_idx0_0, ZPR128, mnemonic> {
  432. bits<4> ZAd;
  433. bits<1> imm;
  434. let Inst{3-0} = ZAd;
  435. }
  436. defm : sme_vector_to_tile_aliases<!cast<Instruction>(NAME # _B),
  437. !if(is_col, TileVectorOpV8,
  438. TileVectorOpH8),
  439. ZPR8, sme_elm_idx0_15>;
  440. defm : sme_vector_to_tile_aliases<!cast<Instruction>(NAME # _H),
  441. !if(is_col, TileVectorOpV16,
  442. TileVectorOpH16),
  443. ZPR16, sme_elm_idx0_7>;
  444. defm : sme_vector_to_tile_aliases<!cast<Instruction>(NAME # _S),
  445. !if(is_col, TileVectorOpV32,
  446. TileVectorOpH32),
  447. ZPR32, sme_elm_idx0_3>;
  448. defm : sme_vector_to_tile_aliases<!cast<Instruction>(NAME # _D),
  449. !if(is_col, TileVectorOpV64,
  450. TileVectorOpH64),
  451. ZPR64, sme_elm_idx0_1>;
  452. defm : sme_vector_to_tile_aliases<!cast<Instruction>(NAME # _Q),
  453. !if(is_col, TileVectorOpV128,
  454. TileVectorOpH128),
  455. ZPR128, sme_elm_idx0_0>;
  456. }
  457. multiclass sme_vector_to_tile<string mnemonic> {
  458. defm _H : sme_vector_v_to_tile<mnemonic, /*is_col=*/0b0>;
  459. defm _V : sme_vector_v_to_tile<mnemonic, /*is_col=*/0b1>;
  460. }
  461. class sme_tile_to_vector_base<bit Q, bit V, bits<2> sz, dag outs, dag ins,
  462. string mnemonic, string argstr>
  463. : I<outs, ins, mnemonic, argstr, "", []>, Sched<[]> {
  464. bits<2> Rv;
  465. bits<3> Pg;
  466. bits<5> Zd;
  467. let Inst{31-24} = 0b11000000;
  468. let Inst{23-22} = sz;
  469. let Inst{21-17} = 0b00001;
  470. let Inst{16} = Q;
  471. let Inst{15} = V;
  472. let Inst{14-13} = Rv;
  473. let Inst{12-10} = Pg;
  474. let Inst{9} = 0b0;
  475. let Inst{4-0} = Zd;
  476. }
  477. class sme_tile_to_vector_inst<bit Q, bits<2> sz, ZPRRegOp zpr_ty,
  478. MatrixTileVectorOperand tile_ty,
  479. bit is_col, Operand imm_ty, string mnemonic>
  480. : sme_tile_to_vector_base<Q, is_col, sz, (outs zpr_ty:$Zd),
  481. (ins PPR3bAny:$Pg, tile_ty:$ZAn, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm),
  482. mnemonic, "\t$Zd, $Pg/m, $ZAn[$Rv, $imm]">;
  483. multiclass sme_tile_to_vector_aliases<Instruction inst, ZPRRegOp zpr_ty,
  484. MatrixTileVectorOperand tile_ty,
  485. Operand imm_ty > {
  486. def : InstAlias<"mov\t$Zd, $Pg/m, $ZAn[$Rv, $imm]",
  487. (inst zpr_ty:$Zd, PPR3bAny:$Pg, tile_ty:$ZAn, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm), 1>;
  488. }
  489. multiclass sme_tile_to_vector_v<string mnemonic, bit is_col> {
  490. def _B : sme_tile_to_vector_inst<0b0, 0b00, ZPR8, !if(is_col, TileVectorOpV8,
  491. TileVectorOpH8),
  492. is_col, sme_elm_idx0_15, mnemonic> {
  493. bits<4> imm;
  494. let Inst{8-5} = imm;
  495. }
  496. def _H : sme_tile_to_vector_inst<0b0, 0b01, ZPR16, !if(is_col, TileVectorOpV16,
  497. TileVectorOpH16),
  498. is_col, sme_elm_idx0_7, mnemonic> {
  499. bits<1> ZAn;
  500. bits<3> imm;
  501. let Inst{8} = ZAn;
  502. let Inst{7-5} = imm;
  503. }
  504. def _S : sme_tile_to_vector_inst<0b0, 0b10, ZPR32, !if(is_col, TileVectorOpV32,
  505. TileVectorOpH32),
  506. is_col, sme_elm_idx0_3, mnemonic> {
  507. bits<2> ZAn;
  508. bits<2> imm;
  509. let Inst{8-7} = ZAn;
  510. let Inst{6-5} = imm;
  511. }
  512. def _D : sme_tile_to_vector_inst<0b0, 0b11, ZPR64, !if(is_col, TileVectorOpV64,
  513. TileVectorOpH64),
  514. is_col, sme_elm_idx0_1, mnemonic> {
  515. bits<3> ZAn;
  516. bits<1> imm;
  517. let Inst{8-6} = ZAn;
  518. let Inst{5} = imm;
  519. }
  520. def _Q : sme_tile_to_vector_inst<0b1, 0b11, ZPR128, !if(is_col, TileVectorOpV128,
  521. TileVectorOpH128),
  522. is_col, sme_elm_idx0_0, mnemonic> {
  523. bits<4> ZAn;
  524. let Inst{8-5} = ZAn;
  525. }
  526. defm : sme_tile_to_vector_aliases<!cast<Instruction>(NAME # _B), ZPR8,
  527. !if(is_col, TileVectorOpV8,
  528. TileVectorOpH8), sme_elm_idx0_15>;
  529. defm : sme_tile_to_vector_aliases<!cast<Instruction>(NAME # _H), ZPR16,
  530. !if(is_col, TileVectorOpV16,
  531. TileVectorOpH16), sme_elm_idx0_7>;
  532. defm : sme_tile_to_vector_aliases<!cast<Instruction>(NAME # _S), ZPR32,
  533. !if(is_col, TileVectorOpV32,
  534. TileVectorOpH32), sme_elm_idx0_3>;
  535. defm : sme_tile_to_vector_aliases<!cast<Instruction>(NAME # _D), ZPR64,
  536. !if(is_col, TileVectorOpV64,
  537. TileVectorOpH64), sme_elm_idx0_1>;
  538. defm : sme_tile_to_vector_aliases<!cast<Instruction>(NAME # _Q), ZPR128,
  539. !if(is_col, TileVectorOpV128,
  540. TileVectorOpH128), sme_elm_idx0_0>;
  541. }
  542. multiclass sme_tile_to_vector<string mnemonic> {
  543. defm _H : sme_tile_to_vector_v<mnemonic, /*is_col=*/0b0>;
  544. defm _V : sme_tile_to_vector_v<mnemonic, /*is_col=*/0b1>;
  545. }
  546. //===----------------------------------------------------------------------===//
  547. // SME Zero
  548. //===----------------------------------------------------------------------===//
  549. class sme_zero_inst<string mnemonic>
  550. : I<(outs MatrixTileList:$imm), (ins),
  551. mnemonic, "\t$imm", "", []>, Sched<[]> {
  552. bits<8> imm;
  553. let Inst{31-8} = 0b110000000000100000000000;
  554. let Inst{7-0} = imm;
  555. }
  556. multiclass sme_zero<string mnemonic> {
  557. def NAME : sme_zero_inst<mnemonic>;
  558. def : InstAlias<"zero\t\\{za\\}", (!cast<Instruction>(NAME) 0b11111111), 1>;
  559. def : InstAlias<"zero\t\\{za0.h\\}", (!cast<Instruction>(NAME) 0b01010101), 1>;
  560. def : InstAlias<"zero\t\\{za1.h\\}", (!cast<Instruction>(NAME) 0b10101010), 1>;
  561. def : InstAlias<"zero\t\\{za0.s\\}", (!cast<Instruction>(NAME) 0b00010001), 1>;
  562. def : InstAlias<"zero\t\\{za1.s\\}", (!cast<Instruction>(NAME) 0b00100010), 1>;
  563. def : InstAlias<"zero\t\\{za2.s\\}", (!cast<Instruction>(NAME) 0b01000100), 1>;
  564. def : InstAlias<"zero\t\\{za3.s\\}", (!cast<Instruction>(NAME) 0b10001000), 1>;
  565. def : InstAlias<"zero\t\\{za0.s,za1.s\\}", (!cast<Instruction>(NAME) 0b00110011), 1>;
  566. def : InstAlias<"zero\t\\{za0.s,za3.s\\}", (!cast<Instruction>(NAME) 0b10011001), 1>;
  567. def : InstAlias<"zero\t\\{za1.s,za2.s\\}", (!cast<Instruction>(NAME) 0b01100110), 1>;
  568. def : InstAlias<"zero\t\\{za2.s,za3.s\\}", (!cast<Instruction>(NAME) 0b11001100), 1>;
  569. def : InstAlias<"zero\t\\{za0.s,za1.s,za2.s\\}", (!cast<Instruction>(NAME) 0b01110111), 1>;
  570. def : InstAlias<"zero\t\\{za0.s,za1.s,za3.s\\}", (!cast<Instruction>(NAME) 0b10111011), 1>;
  571. def : InstAlias<"zero\t\\{za0.s,za2.s,za3.s\\}", (!cast<Instruction>(NAME) 0b11011101), 1>;
  572. def : InstAlias<"zero\t\\{za1.s,za2.s,za3.s\\}", (!cast<Instruction>(NAME) 0b11101110), 1>;
  573. }
  574. //===----------------------------------------------------------------------===//
  575. // SVE2 Instructions
  576. //===----------------------------------------------------------------------===//
  577. class sve2_int_perm_revd<string asm>
  578. : I<(outs ZPR128:$Zd), (ins ZPR128:$_Zd, PPR3bAny:$Pg, ZPR128:$Zn),
  579. asm, "\t$Zd, $Pg/m, $Zn", "", []>,
  580. Sched<[]> {
  581. bits<5> Zd;
  582. bits<3> Pg;
  583. bits<5> Zn;
  584. let Inst{31-24} = 0b00000101;
  585. let Inst{23-22} = 0b00; // size
  586. let Inst{21-13} = 0b101110100;
  587. let Inst{12-10} = Pg;
  588. let Inst{9-5} = Zn;
  589. let Inst{4-0} = Zd;
  590. let Constraints = "$Zd = $_Zd";
  591. let DestructiveInstType = DestructiveUnary;
  592. let ElementSize = ZPR128.ElementSize;
  593. }
  594. class sve2_clamp<string asm, bits<2> sz, bit U, ZPRRegOp zpr_ty>
  595. : I<(outs zpr_ty:$Zd), (ins zpr_ty:$Zn, zpr_ty:$Zm, zpr_ty:$_Zd),
  596. asm, "\t$Zd, $Zn, $Zm", "", []>,
  597. Sched<[]> {
  598. bits<5> Zm;
  599. bits<5> Zn;
  600. bits<5> Zd;
  601. let Inst{31-24} = 0b01000100;
  602. let Inst{23-22} = sz;
  603. let Inst{21} = 0b0;
  604. let Inst{20-16} = Zm;
  605. let Inst{15-11} = 0b11000;
  606. let Inst{10} = U;
  607. let Inst{9-5} = Zn;
  608. let Inst{4-0} = Zd;
  609. let Constraints = "$Zd = $_Zd";
  610. let DestructiveInstType = DestructiveOther;
  611. let ElementSize = zpr_ty.ElementSize;
  612. }
  613. multiclass sve2_clamp<string asm, bit U> {
  614. def _B : sve2_clamp<asm, 0b00, U, ZPR8>;
  615. def _H : sve2_clamp<asm, 0b01, U, ZPR16>;
  616. def _S : sve2_clamp<asm, 0b10, U, ZPR32>;
  617. def _D : sve2_clamp<asm, 0b11, U, ZPR64>;
  618. }
  619. class sve2_int_perm_sel_p<string asm, PPRRegOp ppr_ty, Operand imm_ty>
  620. : I<(outs PPRAny:$Pd), (ins PPRAny:$Pn, ppr_ty:$Pm,
  621. MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm),
  622. asm, "\t$Pd, $Pn, $Pm[$Rv, $imm]", "", []>,
  623. Sched<[]> {
  624. bits<2> Rv;
  625. bits<4> Pn;
  626. bits<4> Pm;
  627. bits<4> Pd;
  628. let Inst{31-24} = 0b00100101;
  629. let Inst{21} = 0b1;
  630. let Inst{17-16} = Rv;
  631. let Inst{15-14} = 0b01;
  632. let Inst{13-10} = Pn;
  633. let Inst{9} = 0b0;
  634. let Inst{8-5} = Pm;
  635. let Inst{4} = 0b0;
  636. let Inst{3-0} = Pd;
  637. }
  638. multiclass sve2_int_perm_sel_p<string asm> {
  639. def _B : sve2_int_perm_sel_p<asm, PPR8, sme_elm_idx0_15> {
  640. bits<4> imm;
  641. let Inst{23-22} = imm{3-2};
  642. let Inst{20-19} = imm{1-0};
  643. let Inst{18} = 0b1;
  644. }
  645. def _H : sve2_int_perm_sel_p<asm, PPR16, sme_elm_idx0_7> {
  646. bits<3> imm;
  647. let Inst{23-22} = imm{2-1};
  648. let Inst{20} = imm{0};
  649. let Inst{19-18} = 0b10;
  650. }
  651. def _S : sve2_int_perm_sel_p<asm, PPR32, sme_elm_idx0_3> {
  652. bits<2> imm;
  653. let Inst{23-22} = imm{1-0};
  654. let Inst{20-18} = 0b100;
  655. }
  656. def _D : sve2_int_perm_sel_p<asm, PPR64, sme_elm_idx0_1> {
  657. bits<1> imm;
  658. let Inst{23} = imm;
  659. let Inst{22} = 0b1;
  660. let Inst{20-18} = 0b000;
  661. }
  662. }