ARMInstrCDE.td 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. //===-- ARMInstrCDE.td - CDE support for ARM ---------------*- 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. // This file describes the Arm CDE (Custom Datapath Extension) instruction set.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. // Immediate operand of arbitrary bit width
  13. class BitWidthImmOperand<int width>
  14. : ImmAsmOperand<0, !add(!shl(1, width), -1)> {
  15. let Name = "Imm"#width#"b";
  16. }
  17. class BitWidthImm<int width>
  18. : Operand<i32>,
  19. ImmLeaf<i32, "{ return Imm >= 0 && Imm < (1 << "#width#"); }"> {
  20. let ParserMatchClass = BitWidthImmOperand<width>;
  21. }
  22. def CDEDualRegOp : RegisterOperand<GPRPairnosp, "printGPRPairOperand">;
  23. // Used by VCX3 FP
  24. def imm_3b : BitWidthImm<3>;
  25. // Used by VCX3 vector
  26. def imm_4b : BitWidthImm<4>;
  27. // Used by VCX2 FP and CX3
  28. def imm_6b : BitWidthImm<6>;
  29. // Used by VCX2 vector
  30. def imm_7b : BitWidthImm<7>;
  31. // Used by CX2
  32. def imm_9b : BitWidthImm<9>;
  33. // Used by VCX1 FP
  34. def imm_11b : BitWidthImm<11>;
  35. // Used by VCX1 vector
  36. def imm_12b : BitWidthImm<12>;
  37. // Used by CX1
  38. def imm_13b : BitWidthImm<13>;
  39. // Base class for all CDE instructions
  40. class CDE_Instr<bit acc, dag oops, dag iops, string asm, string cstr>
  41. : Thumb2XI<oops, !con((ins p_imm:$coproc), iops),
  42. AddrModeNone, /*sz=*/4, NoItinerary,
  43. asm, cstr, /*pattern=*/[]>,
  44. Sched<[]> {
  45. bits<3> coproc;
  46. let Inst{31-29} = 0b111; // 15:13
  47. let Inst{28} = acc;
  48. let Inst{27-26} = 0b11;
  49. let Inst{11} = 0b0;
  50. let Inst{10-8} = coproc{2-0};
  51. let isPredicable = 0;
  52. let DecoderNamespace = "Thumb2CDE";
  53. }
  54. // Base class for CX* CDE instructions
  55. class CDE_GPR_Instr<bit dual, bit acc, dag oops, dag iops,
  56. string asm, string cstr>
  57. : CDE_Instr<acc, oops, iops, asm, cstr>,
  58. Requires<[HasCDE]> {
  59. let Inst{25-24} = 0b10;
  60. let Inst{6} = dual;
  61. let isPredicable = acc;
  62. }
  63. // Set of registers used by the CDE instructions.
  64. class CDE_RegisterOperands {
  65. dag Rd;
  66. dag Rd_src;
  67. dag Rn;
  68. dag Rm;
  69. }
  70. // CX* CDE instruction parameter set
  71. class CX_Params {
  72. dag Oops; // Output operands for CX* instructions
  73. dag Iops1; // Input operands for CX1* instructions
  74. dag Iops2; // Input operands for CX2* instructions
  75. dag Iops3; // Input operands for CX3* instructions
  76. dag PredOp; // Input predicate operand
  77. string PAsm; // Predicate assembly string
  78. string Cstr; // asm constraint string
  79. bit Dual; // "dual" field for encoding
  80. bit Acc; // "acc" field for encoding
  81. }
  82. // VCX* CDE instruction parameter set
  83. class VCX_Params {
  84. dag Oops; // Output operands for VCX* instructions
  85. dag Iops1; // Input operands for VCX1* instructions
  86. dag Iops2; // Input operands for VCX2* instructions
  87. dag Iops3; // Input operands for VCX3* instructions
  88. string Cstr; // asm constraint string
  89. bit Acc; // "acc" field for encoding
  90. vpred_ops Vpred; // Predication type for VCX* vector instructions
  91. }
  92. // CX1, CX1A, CX1D, CX1DA
  93. class CDE_CX1_Instr<string iname, CX_Params params>
  94. : CDE_GPR_Instr<params.Dual, params.Acc, params.Oops,
  95. !con(params.Iops1, (ins imm_13b:$imm), params.PredOp),
  96. !strconcat(iname, params.PAsm, "\t$coproc, $Rd, $imm"),
  97. params.Cstr> {
  98. bits<13> imm;
  99. bits<4> Rd;
  100. let Inst{23-22} = 0b00;
  101. let Inst{21-16} = imm{12-7};
  102. let Inst{15-12} = Rd{3-0};
  103. let Inst{7} = imm{6};
  104. let Inst{5-0} = imm{5-0};
  105. }
  106. // CX2, CX2A, CX2D, CX2DA
  107. class CDE_CX2_Instr<string iname, CX_Params params>
  108. : CDE_GPR_Instr<params.Dual, params.Acc, params.Oops,
  109. !con(params.Iops2, (ins imm_9b:$imm), params.PredOp),
  110. !strconcat(iname, params.PAsm, "\t$coproc, $Rd, $Rn, $imm"),
  111. params.Cstr> {
  112. bits<9> imm;
  113. bits<4> Rd;
  114. bits<4> Rn;
  115. let Inst{23-22} = 0b01;
  116. let Inst{21-20} = imm{8-7};
  117. let Inst{19-16} = Rn{3-0};
  118. let Inst{15-12} = Rd{3-0};
  119. let Inst{7} = imm{6};
  120. let Inst{5-0} = imm{5-0};
  121. }
  122. // CX3, CX3A, CX3D, CX3DA
  123. class CDE_CX3_Instr<string iname, CX_Params params>
  124. : CDE_GPR_Instr<params.Dual, params.Acc, params.Oops,
  125. !con(params.Iops3, (ins imm_6b:$imm), params.PredOp),
  126. !strconcat(iname, params.PAsm, "\t$coproc, $Rd, $Rn, $Rm, $imm"),
  127. params.Cstr> {
  128. bits<6> imm;
  129. bits<4> Rd;
  130. bits<4> Rn;
  131. bits<4> Rm;
  132. let Inst{23} = 0b1;
  133. let Inst{22-20} = imm{5-3};
  134. let Inst{19-16} = Rn{3-0};
  135. let Inst{15-12} = Rm{3-0};
  136. let Inst{7} = imm{2};
  137. let Inst{5-4} = imm{1-0};
  138. let Inst{3-0} = Rd{3-0};
  139. }
  140. // Registers for single-register variants of CX* instructions
  141. def cde_cx_single_regs : CDE_RegisterOperands {
  142. let Rd = (outs GPRwithAPSR_NZCVnosp:$Rd);
  143. let Rd_src = (ins GPRwithAPSR_NZCVnosp:$Rd_src);
  144. let Rn = (ins GPRwithAPSR_NZCVnosp:$Rn);
  145. let Rm = (ins GPRwithAPSR_NZCVnosp:$Rm);
  146. }
  147. // Registers for single-register variants of CX* instructions
  148. def cde_cx_dual_regs : CDE_RegisterOperands {
  149. let Rd = (outs CDEDualRegOp:$Rd);
  150. let Rd_src = (ins CDEDualRegOp:$Rd_src);
  151. let Rn = (ins GPRwithAPSR_NZCVnosp:$Rn);
  152. let Rm = (ins GPRwithAPSR_NZCVnosp:$Rm);
  153. }
  154. class CDE_CX_ParamsTemplate<bit dual, bit acc, CDE_RegisterOperands ops>
  155. : CX_Params {
  156. dag IOpsPrefix = !if(acc, ops.Rd_src, (ins));
  157. let Oops = ops.Rd;
  158. let Iops1 = IOpsPrefix;
  159. let Iops2 = !con(IOpsPrefix, ops.Rn);
  160. let Iops3 = !con(IOpsPrefix, ops.Rn, ops.Rm);
  161. let PredOp = !if(acc, (ins pred:$p), (ins));
  162. let PAsm = !if(acc, "${p}", "");
  163. let Cstr = !if(acc, "$Rd = $Rd_src", "");
  164. let Dual = dual;
  165. let Acc = acc;
  166. }
  167. def cde_cx_params_single_noacc : CDE_CX_ParamsTemplate<0b0, 0b0, cde_cx_single_regs>;
  168. def cde_cx_params_single_acc : CDE_CX_ParamsTemplate<0b0, 0b1, cde_cx_single_regs>;
  169. def cde_cx_params_dual_noacc : CDE_CX_ParamsTemplate<0b1, 0b0, cde_cx_dual_regs>;
  170. def cde_cx_params_dual_acc : CDE_CX_ParamsTemplate<0b1, 0b1, cde_cx_dual_regs>;
  171. def CDE_CX1 : CDE_CX1_Instr<"cx1", cde_cx_params_single_noacc>;
  172. def CDE_CX1A : CDE_CX1_Instr<"cx1a", cde_cx_params_single_acc>;
  173. def CDE_CX1D : CDE_CX1_Instr<"cx1d", cde_cx_params_dual_noacc>;
  174. def CDE_CX1DA : CDE_CX1_Instr<"cx1da", cde_cx_params_dual_acc>;
  175. def CDE_CX2 : CDE_CX2_Instr<"cx2", cde_cx_params_single_noacc>;
  176. def CDE_CX2A : CDE_CX2_Instr<"cx2a", cde_cx_params_single_acc>;
  177. def CDE_CX2D : CDE_CX2_Instr<"cx2d", cde_cx_params_dual_noacc>;
  178. def CDE_CX2DA : CDE_CX2_Instr<"cx2da", cde_cx_params_dual_acc>;
  179. def CDE_CX3 : CDE_CX3_Instr<"cx3", cde_cx_params_single_noacc>;
  180. def CDE_CX3A : CDE_CX3_Instr<"cx3a", cde_cx_params_single_acc>;
  181. def CDE_CX3D : CDE_CX3_Instr<"cx3d", cde_cx_params_dual_noacc>;
  182. def CDE_CX3DA : CDE_CX3_Instr<"cx3da", cde_cx_params_dual_acc>;
  183. let Predicates = [HasCDE] in {
  184. def : Pat<(i32 (int_arm_cde_cx1 timm:$coproc, timm:$imm)),
  185. (i32 (CDE_CX1 p_imm:$coproc, imm_13b:$imm))>;
  186. def : Pat<(i32 (int_arm_cde_cx1a timm:$coproc, GPRwithAPSR_NZCVnosp:$acc,
  187. timm:$imm)),
  188. (i32 (CDE_CX1A p_imm:$coproc, GPRwithAPSR_NZCVnosp:$acc,
  189. imm_13b:$imm))>;
  190. def : Pat<(i32 (int_arm_cde_cx2 timm:$coproc, GPRwithAPSR_NZCVnosp:$n,
  191. timm:$imm)),
  192. (i32 (CDE_CX2 p_imm:$coproc, GPRwithAPSR_NZCVnosp:$n,
  193. imm_9b:$imm))>;
  194. def : Pat<(i32 (int_arm_cde_cx2a timm:$coproc, GPRwithAPSR_NZCVnosp:$acc,
  195. GPRwithAPSR_NZCVnosp:$n, timm:$imm)),
  196. (i32 (CDE_CX2A p_imm:$coproc, GPRwithAPSR_NZCVnosp:$acc,
  197. GPRwithAPSR_NZCVnosp:$n, imm_9b:$imm))>;
  198. def : Pat<(i32 (int_arm_cde_cx3 timm:$coproc, GPRwithAPSR_NZCVnosp:$n,
  199. GPRwithAPSR_NZCVnosp:$m, timm:$imm)),
  200. (i32 (CDE_CX3 p_imm:$coproc, GPRwithAPSR_NZCVnosp:$n,
  201. GPRwithAPSR_NZCVnosp:$m, imm_6b:$imm))>;
  202. def : Pat<(i32 (int_arm_cde_cx3a timm:$coproc,
  203. GPRwithAPSR_NZCVnosp:$acc,
  204. GPRwithAPSR_NZCVnosp:$n,
  205. GPRwithAPSR_NZCVnosp:$m, timm:$imm)),
  206. (i32 (CDE_CX3A p_imm:$coproc,
  207. GPRwithAPSR_NZCVnosp:$acc,
  208. GPRwithAPSR_NZCVnosp:$n,
  209. GPRwithAPSR_NZCVnosp:$m, imm_6b:$imm))>;
  210. }
  211. class CDE_RequiresSReg : Requires<[HasCDE, HasFPRegs]>;
  212. class CDE_RequiresDReg : Requires<[HasCDE, HasFPRegs]>;
  213. class CDE_RequiresQReg : Requires<[HasCDE, HasMVEInt]>;
  214. // Base class for CDE VCX* instructions
  215. class CDE_FP_Vec_Instr<bit vec, bit acc, dag oops, dag iops, string asm, string cstr>
  216. : CDE_Instr<acc, oops, iops, asm, cstr> {
  217. let Inst{25} = 0b0;
  218. let Inst{6} = vec;
  219. }
  220. // Base class for floating-point variants of CDE VCX* instructions
  221. class CDE_FP_Instr<bit acc, bit sz, dag oops, dag iops, string asm, string cstr>
  222. : CDE_FP_Vec_Instr<0b0, acc, oops, iops, asm, cstr> {
  223. let Inst{24} = sz;
  224. }
  225. // Base class for vector variants of CDE VCX* instruction
  226. class CDE_Vec_Instr<bit acc, dag oops, dag iops, string asm, string cstr,
  227. vpred_ops vpred>
  228. : CDE_FP_Vec_Instr<0b1, acc, oops,
  229. !con(iops, (ins vpred:$vp)), asm,
  230. !strconcat(cstr, vpred.vpred_constraint)>,
  231. CDE_RequiresQReg {
  232. }
  233. // VCX1/VCX1A, vector variant
  234. class CDE_VCX1_Vec_Instr<string iname, VCX_Params params>
  235. : CDE_Vec_Instr<params.Acc, params.Oops,
  236. !con(params.Iops1, (ins imm_12b:$imm)),
  237. iname#"${vp}\t$coproc, $Qd, $imm", params.Cstr, params.Vpred> {
  238. bits<12> imm;
  239. bits<3> Qd;
  240. let Inst{24} = imm{11};
  241. let Inst{23} = 0b0;
  242. let Inst{22} = 0b0;
  243. let Inst{21-20} = 0b10;
  244. let Inst{19-16} = imm{10-7};
  245. let Inst{15-13} = Qd{2-0};
  246. let Inst{12} = 0b0;
  247. let Inst{7} = imm{6};
  248. let Inst{5-0} = imm{5-0};
  249. let Unpredictable{22} = 0b1;
  250. }
  251. // VCX1/VCX1A, base class for FP variants
  252. class CDE_VCX1_FP_Instr<bit sz, string iname, VCX_Params params>
  253. : CDE_FP_Instr<params.Acc, sz, params.Oops,
  254. !con(params.Iops1, (ins imm_11b:$imm)),
  255. iname#"\t$coproc, $Vd, $imm", params.Cstr> {
  256. bits<11> imm;
  257. let Inst{23} = 0b0;
  258. let Inst{21-20} = 0b10;
  259. let Inst{19-16} = imm{10-7};
  260. let Inst{7} = imm{6};
  261. let Inst{5-0} = imm{5-0};
  262. }
  263. // VCX1/VCX1A, S registers
  264. class CDE_VCX1_FP_Instr_S<string iname, VCX_Params params>
  265. : CDE_VCX1_FP_Instr<0b0, iname, params>,
  266. CDE_RequiresSReg {
  267. bits<5> Vd;
  268. let Inst{22} = Vd{0};
  269. let Inst{15-12} = Vd{4-1};
  270. }
  271. // VCX1/VCX1A, D registers
  272. class CDE_VCX1_FP_Instr_D<string iname, VCX_Params params>
  273. : CDE_VCX1_FP_Instr<0b1, iname, params>,
  274. CDE_RequiresDReg {
  275. bits<5> Vd;
  276. let Inst{22} = Vd{4};
  277. let Inst{15-12} = Vd{3-0};
  278. }
  279. // VCX2/VCX2A, vector variant
  280. class CDE_VCX2_Vec_Instr<string iname, VCX_Params params>
  281. : CDE_Vec_Instr<params.Acc, params.Oops,
  282. !con(params.Iops2, (ins imm_7b:$imm)),
  283. iname#"${vp}\t$coproc, $Qd, $Qm, $imm", params.Cstr,
  284. params.Vpred> {
  285. bits<7> imm;
  286. bits<3> Qd;
  287. bits<3> Qm;
  288. let Inst{24} = imm{6};
  289. let Inst{23} = 0b0;
  290. let Inst{22} = 0b0;
  291. let Inst{21-20} = 0b11;
  292. let Inst{19-16} = imm{5-2};
  293. let Inst{15-13} = Qd{2-0};
  294. let Inst{12} = 0b0;
  295. let Inst{7} = imm{1};
  296. let Inst{5} = 0b0;
  297. let Inst{4} = imm{0};
  298. let Inst{3-1} = Qm{2-0};
  299. let Inst{0} = 0b0;
  300. let Unpredictable{22} = 0b1;
  301. let Unpredictable{5} = 0b1;
  302. }
  303. // VCX2/VCX2A, base class for FP variants
  304. class CDE_VCX2_FP_Instr<bit sz, string iname, VCX_Params params>
  305. : CDE_FP_Instr<params.Acc, sz, params.Oops,
  306. !con(params.Iops2, (ins imm_6b:$imm)),
  307. iname#"\t$coproc, $Vd, $Vm, $imm", params.Cstr> {
  308. bits<6> imm;
  309. let Inst{23} = 0b0;
  310. let Inst{21-20} = 0b11;
  311. let Inst{19-16} = imm{5-2};
  312. let Inst{7} = imm{1};
  313. let Inst{4} = imm{0};
  314. }
  315. // VCX2/VCX2A, S registers
  316. class CDE_VCX2_FP_Instr_S<string iname, VCX_Params params>
  317. : CDE_VCX2_FP_Instr<0b0, iname, params>,
  318. CDE_RequiresSReg {
  319. bits<5> Vd;
  320. bits<5> Vm;
  321. let Inst{15-12} = Vd{4-1};
  322. let Inst{22} = Vd{0};
  323. let Inst{3-0} = Vm{4-1};
  324. let Inst{5} = Vm{0};
  325. }
  326. // VCX2/VCX2A, D registers
  327. class CDE_VCX2_FP_Instr_D<string iname, VCX_Params params>
  328. : CDE_VCX2_FP_Instr<0b1, iname, params>,
  329. CDE_RequiresDReg {
  330. bits<5> Vd;
  331. bits<5> Vm;
  332. let Inst{15-12} = Vd{3-0};
  333. let Inst{22} = Vd{4};
  334. let Inst{3-0} = Vm{3-0};
  335. let Inst{5} = Vm{4};
  336. }
  337. // VCX3/VCX3A, vector variant
  338. class CDE_VCX3_Vec_Instr<string iname, VCX_Params params>
  339. : CDE_Vec_Instr<params.Acc, params.Oops,
  340. !con(params.Iops3, (ins imm_4b:$imm)),
  341. iname#"${vp}\t$coproc, $Qd, $Qn, $Qm, $imm", params.Cstr,
  342. params.Vpred> {
  343. bits<4> imm;
  344. bits<3> Qd;
  345. bits<3> Qm;
  346. bits<3> Qn;
  347. let Inst{24} = imm{3};
  348. let Inst{23} = 0b1;
  349. let Inst{22} = 0b0;
  350. let Inst{21-20} = imm{2-1};
  351. let Inst{19-17} = Qn{2-0};
  352. let Inst{16} = 0b0;
  353. let Inst{15-13} = Qd{2-0};
  354. let Inst{12} = 0b0;
  355. let Inst{7} = 0b0;
  356. let Inst{5} = 0b0;
  357. let Inst{4} = imm{0};
  358. let Inst{3-1} = Qm{2-0};
  359. let Inst{0} = 0b0;
  360. let Unpredictable{22} = 0b1;
  361. let Unpredictable{7} = 0b1;
  362. let Unpredictable{5} = 0b1;
  363. }
  364. // VCX3/VCX3A, base class for FP variants
  365. class CDE_VCX3_FP_Instr<bit sz, string iname, VCX_Params params>
  366. : CDE_FP_Instr<params.Acc, sz, params.Oops,
  367. !con(params.Iops3, (ins imm_3b:$imm)),
  368. iname#"\t$coproc, $Vd, $Vn, $Vm, $imm", params.Cstr> {
  369. bits<3> imm;
  370. let Inst{23} = 0b1;
  371. let Inst{21-20} = imm{2-1};
  372. let Inst{4} = imm{0};
  373. }
  374. // VCX3/VCX3A, S registers
  375. class CDE_VCX3_FP_Instr_S<string iname, VCX_Params params>
  376. : CDE_VCX3_FP_Instr<0b0, iname, params>,
  377. CDE_RequiresSReg {
  378. bits<5> Vd;
  379. bits<5> Vm;
  380. bits<5> Vn;
  381. let Inst{22} = Vd{0};
  382. let Inst{19-16} = Vn{4-1};
  383. let Inst{15-12} = Vd{4-1};
  384. let Inst{7} = Vn{0};
  385. let Inst{5} = Vm{0};
  386. let Inst{3-0} = Vm{4-1};
  387. }
  388. // VCX3/VCX3A, D registers
  389. class CDE_VCX3_FP_Instr_D<string iname, VCX_Params params>
  390. : CDE_VCX3_FP_Instr<0b1, iname, params>,
  391. CDE_RequiresDReg {
  392. bits<5> Vd;
  393. bits<5> Vm;
  394. bits<5> Vn;
  395. let Inst{22} = Vd{4};
  396. let Inst{19-16} = Vn{3-0};
  397. let Inst{15-12} = Vd{3-0};
  398. let Inst{7} = Vn{4};
  399. let Inst{5} = Vm{4};
  400. let Inst{3-0} = Vm{3-0};
  401. }
  402. // Register operands for VCX* instructions
  403. class CDE_VCX_RegisterOperandsTemplate<RegisterClass regclass>
  404. : CDE_RegisterOperands {
  405. let Rd = (outs regclass:$Vd);
  406. let Rd_src = (ins regclass:$Vd_src);
  407. let Rn = (ins regclass:$Vn);
  408. let Rm = (ins regclass:$Vm);
  409. }
  410. class CDE_VCXQ_RegisterOperandsTemplate<RegisterClass regclass>
  411. : CDE_RegisterOperands {
  412. let Rd = (outs regclass:$Qd);
  413. let Rd_src = (ins regclass:$Qd_src);
  414. let Rn = (ins regclass:$Qn);
  415. let Rm = (ins regclass:$Qm);
  416. }
  417. def cde_vcx_s_regs : CDE_VCX_RegisterOperandsTemplate<SPR>;
  418. def cde_vcx_d_regs : CDE_VCX_RegisterOperandsTemplate<DPR_VFP2>;
  419. def cde_vcx_q_regs : CDE_VCXQ_RegisterOperandsTemplate<MQPR>;
  420. class CDE_VCX_ParamsTemplate<bit acc, CDE_RegisterOperands ops>
  421. : VCX_Params {
  422. dag IOpsPrefix = !if(acc, ops.Rd_src, (ins));
  423. let Oops = ops.Rd;
  424. let Iops1 = IOpsPrefix;
  425. let Iops2 = !con(IOpsPrefix, ops.Rm);
  426. let Iops3 = !con(IOpsPrefix, ops.Rn, ops.Rm);
  427. let Cstr = !if(acc, "$Vd = $Vd_src", "");
  428. let Acc = acc;
  429. }
  430. class CDE_VCXQ_ParamsTemplate<bit acc, CDE_RegisterOperands ops>
  431. : VCX_Params {
  432. dag IOpsPrefix = !if(acc, ops.Rd_src, (ins));
  433. let Oops = ops.Rd;
  434. let Iops1 = IOpsPrefix;
  435. let Iops2 = !con(IOpsPrefix, ops.Rm);
  436. let Iops3 = !con(IOpsPrefix, ops.Rn, ops.Rm);
  437. let Cstr = !if(acc, "$Qd = $Qd_src", "");
  438. let Acc = acc;
  439. let Vpred = !if(acc, vpred_n, vpred_r);
  440. }
  441. def cde_vcx_params_s_noacc : CDE_VCX_ParamsTemplate<0b0, cde_vcx_s_regs>;
  442. def cde_vcx_params_s_acc : CDE_VCX_ParamsTemplate<0b1, cde_vcx_s_regs>;
  443. def cde_vcx_params_d_noacc : CDE_VCX_ParamsTemplate<0b0, cde_vcx_d_regs>;
  444. def cde_vcx_params_d_acc : CDE_VCX_ParamsTemplate<0b1, cde_vcx_d_regs>;
  445. def cde_vcx_params_q_noacc : CDE_VCXQ_ParamsTemplate<0b0, cde_vcx_q_regs>;
  446. def cde_vcx_params_q_acc : CDE_VCXQ_ParamsTemplate<0b1, cde_vcx_q_regs>;
  447. def CDE_VCX1_fpsp : CDE_VCX1_FP_Instr_S<"vcx1", cde_vcx_params_s_noacc>;
  448. def CDE_VCX1A_fpsp : CDE_VCX1_FP_Instr_S<"vcx1a", cde_vcx_params_s_acc>;
  449. def CDE_VCX1_fpdp : CDE_VCX1_FP_Instr_D<"vcx1", cde_vcx_params_d_noacc>;
  450. def CDE_VCX1A_fpdp : CDE_VCX1_FP_Instr_D<"vcx1a", cde_vcx_params_d_acc>;
  451. def CDE_VCX1_vec : CDE_VCX1_Vec_Instr<"vcx1", cde_vcx_params_q_noacc>;
  452. def CDE_VCX1A_vec : CDE_VCX1_Vec_Instr<"vcx1a", cde_vcx_params_q_acc>;
  453. def CDE_VCX2_fpsp : CDE_VCX2_FP_Instr_S<"vcx2", cde_vcx_params_s_noacc>;
  454. def CDE_VCX2A_fpsp : CDE_VCX2_FP_Instr_S<"vcx2a", cde_vcx_params_s_acc>;
  455. def CDE_VCX2_fpdp : CDE_VCX2_FP_Instr_D<"vcx2", cde_vcx_params_d_noacc>;
  456. def CDE_VCX2A_fpdp : CDE_VCX2_FP_Instr_D<"vcx2a", cde_vcx_params_d_acc>;
  457. def CDE_VCX2_vec : CDE_VCX2_Vec_Instr<"vcx2", cde_vcx_params_q_noacc>;
  458. def CDE_VCX2A_vec : CDE_VCX2_Vec_Instr<"vcx2a", cde_vcx_params_q_acc>;
  459. def CDE_VCX3_fpsp : CDE_VCX3_FP_Instr_S<"vcx3", cde_vcx_params_s_noacc>;
  460. def CDE_VCX3A_fpsp : CDE_VCX3_FP_Instr_S<"vcx3a", cde_vcx_params_s_acc>;
  461. def CDE_VCX3_fpdp : CDE_VCX3_FP_Instr_D<"vcx3", cde_vcx_params_d_noacc>;
  462. def CDE_VCX3A_fpdp : CDE_VCX3_FP_Instr_D<"vcx3a", cde_vcx_params_d_acc>;
  463. def CDE_VCX3_vec : CDE_VCX3_Vec_Instr<"vcx3", cde_vcx_params_q_noacc>;
  464. def CDE_VCX3A_vec : CDE_VCX3_Vec_Instr<"vcx3a", cde_vcx_params_q_acc>;
  465. let Predicates = [HasCDE, HasFPRegs] in {
  466. def : Pat<(f32 (int_arm_cde_vcx1 timm:$coproc, timm:$imm)),
  467. (f32 (CDE_VCX1_fpsp p_imm:$coproc, imm_11b:$imm))>;
  468. def : Pat<(f32 (int_arm_cde_vcx1a timm:$coproc, (f32 SPR:$acc), timm:$imm)),
  469. (f32 (CDE_VCX1A_fpsp p_imm:$coproc, SPR:$acc, imm_11b:$imm))>;
  470. def : Pat<(f64 (int_arm_cde_vcx1 timm:$coproc, timm:$imm)),
  471. (f64 (CDE_VCX1_fpdp p_imm:$coproc, imm_11b:$imm))>;
  472. def : Pat<(f64 (int_arm_cde_vcx1a timm:$coproc, (f64 DPR:$acc), timm:$imm)),
  473. (f64 (CDE_VCX1A_fpdp p_imm:$coproc, DPR:$acc, imm_11b:$imm))>;
  474. def : Pat<(f32 (int_arm_cde_vcx2 timm:$coproc, (f32 SPR:$n), timm:$imm)),
  475. (f32 (CDE_VCX2_fpsp p_imm:$coproc, SPR:$n, imm_6b:$imm))>;
  476. def : Pat<(f32 (int_arm_cde_vcx2a timm:$coproc, (f32 SPR:$acc), (f32 SPR:$n),
  477. timm:$imm)),
  478. (f32 (CDE_VCX2A_fpsp p_imm:$coproc, SPR:$acc, SPR:$n, imm_6b:$imm))>;
  479. def : Pat<(f64 (int_arm_cde_vcx2 timm:$coproc, (f64 DPR:$n), timm:$imm)),
  480. (f64 (CDE_VCX2_fpdp p_imm:$coproc, DPR:$n, imm_6b:$imm))>;
  481. def : Pat<(f64 (int_arm_cde_vcx2a timm:$coproc, (f64 DPR:$acc), (f64 DPR:$n),
  482. timm:$imm)),
  483. (f64 (CDE_VCX2A_fpdp p_imm:$coproc, DPR:$acc, DPR:$n, imm_6b:$imm))>;
  484. def : Pat<(f32 (int_arm_cde_vcx3 timm:$coproc, (f32 SPR:$n), (f32 SPR:$m),
  485. timm:$imm)),
  486. (f32 (CDE_VCX3_fpsp p_imm:$coproc, (f32 SPR:$n), (f32 SPR:$m),
  487. imm_3b:$imm))>;
  488. def : Pat<(f32 (int_arm_cde_vcx3a timm:$coproc, (f32 SPR:$acc), (f32 SPR:$n),
  489. (f32 SPR:$m), timm:$imm)),
  490. (f32 (CDE_VCX3A_fpsp p_imm:$coproc, SPR:$acc, SPR:$n, SPR:$m,
  491. imm_3b:$imm))>;
  492. def : Pat<(f64 (int_arm_cde_vcx3 timm:$coproc, (f64 DPR:$n), (f64 DPR:$m),
  493. timm:$imm)),
  494. (f64 (CDE_VCX3_fpdp p_imm:$coproc, DPR:$n, DPR:$m, imm_3b:$imm))>;
  495. def : Pat<(f64 (int_arm_cde_vcx3a timm:$coproc, (f64 DPR:$acc), (f64 DPR:$n),
  496. (f64 DPR:$m), timm:$imm)),
  497. (f64 (CDE_VCX3A_fpdp p_imm:$coproc, DPR:$acc, DPR:$n, DPR:$m,
  498. imm_3b:$imm))>;
  499. }
  500. let Predicates = [HasCDE, HasMVEInt] in {
  501. def : Pat<(v16i8 (int_arm_cde_vcx1q timm:$coproc, timm:$imm)),
  502. (v16i8 (CDE_VCX1_vec p_imm:$coproc, imm_12b:$imm))>;
  503. def : Pat<(v16i8 (int_arm_cde_vcx1qa timm:$coproc, (v16i8 MQPR:$acc),
  504. timm:$imm)),
  505. (v16i8 (CDE_VCX1A_vec p_imm:$coproc, MQPR:$acc, imm_12b:$imm))>;
  506. def : Pat<(v16i8 (int_arm_cde_vcx2q timm:$coproc, (v16i8 MQPR:$n), timm:$imm)),
  507. (v16i8 (CDE_VCX2_vec p_imm:$coproc, MQPR:$n, imm_7b:$imm))>;
  508. def : Pat<(v16i8 (int_arm_cde_vcx2qa timm:$coproc, (v16i8 MQPR:$acc),
  509. (v16i8 MQPR:$n), timm:$imm)),
  510. (v16i8 (CDE_VCX2A_vec p_imm:$coproc, MQPR:$acc, MQPR:$n,
  511. imm_7b:$imm))>;
  512. def : Pat<(v16i8 (int_arm_cde_vcx3q timm:$coproc, (v16i8 MQPR:$n),
  513. (v16i8 MQPR:$m), timm:$imm)),
  514. (v16i8 (CDE_VCX3_vec p_imm:$coproc, MQPR:$n, MQPR:$m,
  515. imm_4b:$imm))>;
  516. def : Pat<(v16i8 (int_arm_cde_vcx3qa timm:$coproc, (v16i8 MQPR:$acc),
  517. (v16i8 MQPR:$n), (v16i8 MQPR:$m),
  518. timm:$imm)),
  519. (v16i8 (CDE_VCX3A_vec p_imm:$coproc, MQPR:$acc, MQPR:$n, MQPR:$m,
  520. imm_4b:$imm))>;
  521. }
  522. multiclass VCXPredicatedPat_m<MVEVectorVTInfo VTI> {
  523. def : Pat<(VTI.Vec (int_arm_cde_vcx1q_predicated timm:$coproc,
  524. (VTI.Vec MQPR:$inactive), timm:$imm,
  525. (VTI.Pred VCCR:$pred))),
  526. (VTI.Vec (CDE_VCX1_vec p_imm:$coproc, imm_12b:$imm, ARMVCCThen,
  527. (VTI.Pred VCCR:$pred), zero_reg,
  528. (VTI.Vec MQPR:$inactive)))>;
  529. def : Pat<(VTI.Vec (int_arm_cde_vcx1qa_predicated timm:$coproc,
  530. (VTI.Vec MQPR:$acc), timm:$imm,
  531. (VTI.Pred VCCR:$pred))),
  532. (VTI.Vec (CDE_VCX1A_vec p_imm:$coproc, (VTI.Vec MQPR:$acc),
  533. imm_12b:$imm, ARMVCCThen,
  534. (VTI.Pred VCCR:$pred), zero_reg))>;
  535. def : Pat<(VTI.Vec (int_arm_cde_vcx2q_predicated timm:$coproc,
  536. (VTI.Vec MQPR:$inactive),
  537. (v16i8 MQPR:$n), timm:$imm,
  538. (VTI.Pred VCCR:$pred))),
  539. (VTI.Vec (CDE_VCX2_vec p_imm:$coproc, (v16i8 MQPR:$n),
  540. imm_7b:$imm, ARMVCCThen,
  541. (VTI.Pred VCCR:$pred), zero_reg,
  542. (VTI.Vec MQPR:$inactive)))>;
  543. def : Pat<(VTI.Vec (int_arm_cde_vcx2qa_predicated timm:$coproc,
  544. (VTI.Vec MQPR:$acc),
  545. (v16i8 MQPR:$n), timm:$imm,
  546. (VTI.Pred VCCR:$pred))),
  547. (VTI.Vec (CDE_VCX2A_vec p_imm:$coproc, (VTI.Vec MQPR:$acc),
  548. (v16i8 MQPR:$n), timm:$imm, ARMVCCThen,
  549. (VTI.Pred VCCR:$pred), zero_reg))>;
  550. def : Pat<(VTI.Vec (int_arm_cde_vcx3q_predicated timm:$coproc,
  551. (VTI.Vec MQPR:$inactive),
  552. (v16i8 MQPR:$n), (v16i8 MQPR:$m),
  553. timm:$imm,
  554. (VTI.Pred VCCR:$pred))),
  555. (VTI.Vec (CDE_VCX3_vec p_imm:$coproc, (v16i8 MQPR:$n),
  556. (v16i8 MQPR:$m),
  557. imm_4b:$imm, ARMVCCThen,
  558. (VTI.Pred VCCR:$pred), zero_reg,
  559. (VTI.Vec MQPR:$inactive)))>;
  560. def : Pat<(VTI.Vec (int_arm_cde_vcx3qa_predicated timm:$coproc,
  561. (VTI.Vec MQPR:$acc),
  562. (v16i8 MQPR:$n), (v16i8 MQPR:$m), timm:$imm,
  563. (VTI.Pred VCCR:$pred))),
  564. (VTI.Vec (CDE_VCX3A_vec p_imm:$coproc, (VTI.Vec MQPR:$acc),
  565. (v16i8 MQPR:$n), (v16i8 MQPR:$m),
  566. imm_4b:$imm, ARMVCCThen,
  567. (VTI.Pred VCCR:$pred), zero_reg))>;
  568. }
  569. let Predicates = [HasCDE, HasMVEInt] in
  570. foreach VTI = [ MVE_v16i8, MVE_v8i16, MVE_v4i32, MVE_v2i64 ] in
  571. defm : VCXPredicatedPat_m<VTI>;
  572. let Predicates = [HasCDE, HasMVEFloat] in
  573. foreach VTI = [ MVE_v8f16, MVE_v4f32 ] in
  574. defm : VCXPredicatedPat_m<VTI>;