1 //===-- ARMInstrCDE.td - CDE support for ARM ---------------*- tablegen -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file describes the Arm CDE (Custom Datapath Extension) instruction set.
11 //===----------------------------------------------------------------------===//
13 // Immediate operand of arbitrary bit width
14 class BitWidthImmOperand<int width>
15 : ImmAsmOperand<0, !add(!shl(1, width), -1)> {
16 let Name = "Imm"#width#"b";
19 class BitWidthImm<int width>
21 ImmLeaf<i32, "{ return Imm >= 0 && Imm < (1 << "#width#"); }"> {
22 let ParserMatchClass = BitWidthImmOperand<width>;
25 def CDEDualRegOp : RegisterOperand<GPRPairnosp, "printGPRPairOperand">;
28 def imm_3b : BitWidthImm<3>;
30 // Used by VCX3 vector
31 def imm_4b : BitWidthImm<4>;
33 // Used by VCX2 FP and CX3
34 def imm_6b : BitWidthImm<6>;
36 // Used by VCX2 vector
37 def imm_7b : BitWidthImm<7>;
40 def imm_9b : BitWidthImm<9>;
43 def imm_11b : BitWidthImm<11>;
45 // Used by VCX1 vector
46 def imm_12b : BitWidthImm<12>;
49 def imm_13b : BitWidthImm<13>;
51 // Base class for all CDE instructions
52 class CDE_Instr<bit acc, dag oops, dag iops, string asm, string cstr>
53 : Thumb2XI<oops, !con((ins p_imm:$coproc), iops),
54 AddrModeNone, /*sz=*/4, NoItinerary,
55 asm, cstr, /*pattern=*/[]>,
59 let Inst{31-29} = 0b111; // 15:13
61 let Inst{27-26} = 0b11;
63 let Inst{10-8} = coproc{2-0};
66 let DecoderNamespace = "Thumb2CDE";
69 // Base class for CX* CDE instructions
70 class CDE_GPR_Instr<bit dual, bit acc, dag oops, dag iops,
71 string asm, string cstr>
72 : CDE_Instr<acc, oops, iops, asm, cstr>,
75 let Inst{25-24} = 0b10;
77 let isPredicable = acc;
80 // Set of registers used by the CDE instructions.
81 class CDE_RegisterOperands {
88 // CX* CDE instruction parameter set
90 dag Oops; // Output operands for CX* instructions
91 dag Iops1; // Input operands for CX1* instructions
92 dag Iops2; // Input operands for CX2* instructions
93 dag Iops3; // Input operands for CX3* instructions
94 dag PredOp; // Input predicate operand
95 string PAsm; // Predicate assembly string
96 string Cstr; // asm constraint string
97 bit Dual; // "dual" field for encoding
98 bit Acc; // "acc" field for encoding
101 // VCX* CDE instruction parameter set
103 dag Oops; // Output operands for VCX* instructions
104 dag Iops1; // Input operands for VCX1* instructions
105 dag Iops2; // Input operands for VCX2* instructions
106 dag Iops3; // Input operands for VCX3* instructions
107 string Cstr; // asm constraint string
108 bit Acc; // "acc" field for encoding
109 vpred_ops Vpred; // Predication type for VCX* vector instructions
112 // CX1, CX1A, CX1D, CX1DA
113 class CDE_CX1_Instr<string iname, CX_Params params>
114 : CDE_GPR_Instr<params.Dual, params.Acc, params.Oops,
115 !con(params.Iops1, (ins imm_13b:$imm), params.PredOp),
116 !strconcat(iname, params.PAsm, "\t$coproc, $Rd, $imm"),
121 let Inst{23-22} = 0b00;
122 let Inst{21-16} = imm{12-7};
123 let Inst{15-12} = Rd{3-0};
124 let Inst{7} = imm{6};
125 let Inst{5-0} = imm{5-0};
128 // CX2, CX2A, CX2D, CX2DA
129 class CDE_CX2_Instr<string iname, CX_Params params>
130 : CDE_GPR_Instr<params.Dual, params.Acc, params.Oops,
131 !con(params.Iops2, (ins imm_9b:$imm), params.PredOp),
132 !strconcat(iname, params.PAsm, "\t$coproc, $Rd, $Rn, $imm"),
138 let Inst{23-22} = 0b01;
139 let Inst{21-20} = imm{8-7};
140 let Inst{19-16} = Rn{3-0};
141 let Inst{15-12} = Rd{3-0};
142 let Inst{7} = imm{6};
143 let Inst{5-0} = imm{5-0};
146 // CX3, CX3A, CX3D, CX3DA
147 class CDE_CX3_Instr<string iname, CX_Params params>
148 : CDE_GPR_Instr<params.Dual, params.Acc, params.Oops,
149 !con(params.Iops3, (ins imm_6b:$imm), params.PredOp),
150 !strconcat(iname, params.PAsm, "\t$coproc, $Rd, $Rn, $Rm, $imm"),
158 let Inst{22-20} = imm{5-3};
159 let Inst{19-16} = Rn{3-0};
160 let Inst{15-12} = Rm{3-0};
161 let Inst{7} = imm{2};
162 let Inst{5-4} = imm{1-0};
163 let Inst{3-0} = Rd{3-0};
166 // Registers for single-register variants of CX* instructions
167 def cde_cx_single_regs : CDE_RegisterOperands {
168 let Rd = (outs GPRwithAPSR_NZCVnosp:$Rd);
169 let Rd_src = (ins GPRwithAPSR_NZCVnosp:$Rd_src);
170 let Rn = (ins GPRwithAPSR_NZCVnosp:$Rn);
171 let Rm = (ins GPRwithAPSR_NZCVnosp:$Rm);
174 // Registers for single-register variants of CX* instructions
175 def cde_cx_dual_regs : CDE_RegisterOperands {
176 let Rd = (outs CDEDualRegOp:$Rd);
177 let Rd_src = (ins CDEDualRegOp:$Rd_src);
178 let Rn = (ins GPRwithAPSR_NZCVnosp:$Rn);
179 let Rm = (ins GPRwithAPSR_NZCVnosp:$Rm);
182 class CDE_CX_ParamsTemplate<bit dual, bit acc, CDE_RegisterOperands ops>
185 dag IOpsPrefix = !if(acc, ops.Rd_src, (ins));
188 let Iops1 = IOpsPrefix;
189 let Iops2 = !con(IOpsPrefix, ops.Rn);
190 let Iops3 = !con(IOpsPrefix, ops.Rn, ops.Rm);
191 let PredOp = !if(acc, (ins pred:$p), (ins));
192 let PAsm = !if(acc, "${p}", "");
193 let Cstr = !if(acc, "$Rd = $Rd_src", "");
198 def cde_cx_params_single_noacc : CDE_CX_ParamsTemplate<0b0, 0b0, cde_cx_single_regs>;
199 def cde_cx_params_single_acc : CDE_CX_ParamsTemplate<0b0, 0b1, cde_cx_single_regs>;
200 def cde_cx_params_dual_noacc : CDE_CX_ParamsTemplate<0b1, 0b0, cde_cx_dual_regs>;
201 def cde_cx_params_dual_acc : CDE_CX_ParamsTemplate<0b1, 0b1, cde_cx_dual_regs>;
203 def CDE_CX1 : CDE_CX1_Instr<"cx1", cde_cx_params_single_noacc>;
204 def CDE_CX1A : CDE_CX1_Instr<"cx1a", cde_cx_params_single_acc>;
205 def CDE_CX1D : CDE_CX1_Instr<"cx1d", cde_cx_params_dual_noacc>;
206 def CDE_CX1DA : CDE_CX1_Instr<"cx1da", cde_cx_params_dual_acc>;
208 def CDE_CX2 : CDE_CX2_Instr<"cx2", cde_cx_params_single_noacc>;
209 def CDE_CX2A : CDE_CX2_Instr<"cx2a", cde_cx_params_single_acc>;
210 def CDE_CX2D : CDE_CX2_Instr<"cx2d", cde_cx_params_dual_noacc>;
211 def CDE_CX2DA : CDE_CX2_Instr<"cx2da", cde_cx_params_dual_acc>;
213 def CDE_CX3 : CDE_CX3_Instr<"cx3", cde_cx_params_single_noacc>;
214 def CDE_CX3A : CDE_CX3_Instr<"cx3a", cde_cx_params_single_acc>;
215 def CDE_CX3D : CDE_CX3_Instr<"cx3d", cde_cx_params_dual_noacc>;
216 def CDE_CX3DA : CDE_CX3_Instr<"cx3da", cde_cx_params_dual_acc>;
218 let Predicates = [HasCDE] in {
219 def : Pat<(i32 (int_arm_cde_cx1 timm:$coproc, timm:$imm)),
220 (i32 (CDE_CX1 p_imm:$coproc, imm_13b:$imm))>;
221 def : Pat<(i32 (int_arm_cde_cx1a timm:$coproc, GPRwithAPSR_NZCVnosp:$acc,
223 (i32 (CDE_CX1A p_imm:$coproc, GPRwithAPSR_NZCVnosp:$acc,
225 def : Pat<(i32 (int_arm_cde_cx2 timm:$coproc, GPRwithAPSR_NZCVnosp:$n,
227 (i32 (CDE_CX2 p_imm:$coproc, GPRwithAPSR_NZCVnosp:$n,
229 def : Pat<(i32 (int_arm_cde_cx2a timm:$coproc, GPRwithAPSR_NZCVnosp:$acc,
230 GPRwithAPSR_NZCVnosp:$n, timm:$imm)),
231 (i32 (CDE_CX2A p_imm:$coproc, GPRwithAPSR_NZCVnosp:$acc,
232 GPRwithAPSR_NZCVnosp:$n, imm_9b:$imm))>;
233 def : Pat<(i32 (int_arm_cde_cx3 timm:$coproc, GPRwithAPSR_NZCVnosp:$n,
234 GPRwithAPSR_NZCVnosp:$m, timm:$imm)),
235 (i32 (CDE_CX3 p_imm:$coproc, GPRwithAPSR_NZCVnosp:$n,
236 GPRwithAPSR_NZCVnosp:$m, imm_6b:$imm))>;
237 def : Pat<(i32 (int_arm_cde_cx3a timm:$coproc,
238 GPRwithAPSR_NZCVnosp:$acc,
239 GPRwithAPSR_NZCVnosp:$n,
240 GPRwithAPSR_NZCVnosp:$m, timm:$imm)),
241 (i32 (CDE_CX3A p_imm:$coproc,
242 GPRwithAPSR_NZCVnosp:$acc,
243 GPRwithAPSR_NZCVnosp:$n,
244 GPRwithAPSR_NZCVnosp:$m, imm_6b:$imm))>;
247 class CDE_RequiresSReg : Requires<[HasCDE, HasFPRegs]>;
248 class CDE_RequiresDReg : Requires<[HasCDE, HasFPRegs]>;
249 class CDE_RequiresQReg : Requires<[HasCDE, HasMVEInt]>;
251 // Base class for CDE VCX* instructions
252 class CDE_FP_Vec_Instr<bit vec, bit acc, dag oops, dag iops, string asm, string cstr>
253 : CDE_Instr<acc, oops, iops, asm, cstr> {
258 // Base class for floating-point variants of CDE VCX* instructions
259 class CDE_FP_Instr<bit acc, bit sz, dag oops, dag iops, string asm, string cstr>
260 : CDE_FP_Vec_Instr<0b0, acc, oops, iops, asm, cstr> {
264 // Base class for vector variants of CDE VCX* instruction
265 class CDE_Vec_Instr<bit acc, dag oops, dag iops, string asm, string cstr,
267 : CDE_FP_Vec_Instr<0b1, acc, oops,
268 !con(iops, (ins vpred:$vp)), asm,
269 !strconcat(cstr, vpred.vpred_constraint)>,
274 // VCX1/VCX1A, vector variant
275 class CDE_VCX1_Vec_Instr<string iname, VCX_Params params>
276 : CDE_Vec_Instr<params.Acc, params.Oops,
277 !con(params.Iops1, (ins imm_12b:$imm)),
278 iname#"${vp}\t$coproc, $Qd, $imm", params.Cstr, params.Vpred> {
282 let Inst{24} = imm{11};
285 let Inst{21-20} = 0b10;
286 let Inst{19-16} = imm{10-7};
287 let Inst{15-13} = Qd{2-0};
289 let Inst{7} = imm{6};
290 let Inst{5-0} = imm{5-0};
292 let Unpredictable{22} = 0b1;
295 // VCX1/VCX1A, base class for FP variants
296 class CDE_VCX1_FP_Instr<bit sz, string iname, VCX_Params params>
297 : CDE_FP_Instr<params.Acc, sz, params.Oops,
298 !con(params.Iops1, (ins imm_11b:$imm)),
299 iname#"\t$coproc, $Vd, $imm", params.Cstr> {
303 let Inst{21-20} = 0b10;
304 let Inst{19-16} = imm{10-7};
305 let Inst{7} = imm{6};
306 let Inst{5-0} = imm{5-0};
309 // VCX1/VCX1A, S registers
310 class CDE_VCX1_FP_Instr_S<string iname, VCX_Params params>
311 : CDE_VCX1_FP_Instr<0b0, iname, params>,
315 let Inst{22} = Vd{0};
316 let Inst{15-12} = Vd{4-1};
319 // VCX1/VCX1A, D registers
320 class CDE_VCX1_FP_Instr_D<string iname, VCX_Params params>
321 : CDE_VCX1_FP_Instr<0b1, iname, params>,
325 let Inst{22} = Vd{4};
326 let Inst{15-12} = Vd{3-0};
329 // VCX2/VCX2A, vector variant
330 class CDE_VCX2_Vec_Instr<string iname, VCX_Params params>
331 : CDE_Vec_Instr<params.Acc, params.Oops,
332 !con(params.Iops2, (ins imm_7b:$imm)),
333 iname#"${vp}\t$coproc, $Qd, $Qm, $imm", params.Cstr,
339 let Inst{24} = imm{6};
342 let Inst{21-20} = 0b11;
343 let Inst{19-16} = imm{5-2};
344 let Inst{15-13} = Qd{2-0};
346 let Inst{7} = imm{1};
348 let Inst{4} = imm{0};
349 let Inst{3-1} = Qm{2-0};
352 let Unpredictable{22} = 0b1;
353 let Unpredictable{5} = 0b1;
356 // VCX2/VCX2A, base class for FP variants
357 class CDE_VCX2_FP_Instr<bit sz, string iname, VCX_Params params>
358 : CDE_FP_Instr<params.Acc, sz, params.Oops,
359 !con(params.Iops2, (ins imm_6b:$imm)),
360 iname#"\t$coproc, $Vd, $Vm, $imm", params.Cstr> {
364 let Inst{21-20} = 0b11;
365 let Inst{19-16} = imm{5-2};
366 let Inst{7} = imm{1};
367 let Inst{4} = imm{0};
370 // VCX2/VCX2A, S registers
371 class CDE_VCX2_FP_Instr_S<string iname, VCX_Params params>
372 : CDE_VCX2_FP_Instr<0b0, iname, params>,
377 let Inst{15-12} = Vd{4-1};
378 let Inst{22} = Vd{0};
379 let Inst{3-0} = Vm{4-1};
383 // VCX2/VCX2A, D registers
384 class CDE_VCX2_FP_Instr_D<string iname, VCX_Params params>
385 : CDE_VCX2_FP_Instr<0b1, iname, params>,
390 let Inst{15-12} = Vd{3-0};
391 let Inst{22} = Vd{4};
392 let Inst{3-0} = Vm{3-0};
396 // VCX3/VCX3A, vector variant
397 class CDE_VCX3_Vec_Instr<string iname, VCX_Params params>
398 : CDE_Vec_Instr<params.Acc, params.Oops,
399 !con(params.Iops3, (ins imm_4b:$imm)),
400 iname#"${vp}\t$coproc, $Qd, $Qn, $Qm, $imm", params.Cstr,
407 let Inst{24} = imm{3};
410 let Inst{21-20} = imm{2-1};
411 let Inst{19-17} = Qn{2-0};
413 let Inst{15-13} = Qd{2-0};
417 let Inst{4} = imm{0};
418 let Inst{3-1} = Qm{2-0};
421 let Unpredictable{22} = 0b1;
422 let Unpredictable{7} = 0b1;
423 let Unpredictable{5} = 0b1;
426 // VCX3/VCX3A, base class for FP variants
427 class CDE_VCX3_FP_Instr<bit sz, string iname, VCX_Params params>
428 : CDE_FP_Instr<params.Acc, sz, params.Oops,
429 !con(params.Iops3, (ins imm_3b:$imm)),
430 iname#"\t$coproc, $Vd, $Vn, $Vm, $imm", params.Cstr> {
434 let Inst{21-20} = imm{2-1};
435 let Inst{4} = imm{0};
438 // VCX3/VCX3A, S registers
439 class CDE_VCX3_FP_Instr_S<string iname, VCX_Params params>
440 : CDE_VCX3_FP_Instr<0b0, iname, params>,
446 let Inst{22} = Vd{0};
447 let Inst{19-16} = Vn{4-1};
448 let Inst{15-12} = Vd{4-1};
451 let Inst{3-0} = Vm{4-1};
454 // VCX3/VCX3A, D registers
455 class CDE_VCX3_FP_Instr_D<string iname, VCX_Params params>
456 : CDE_VCX3_FP_Instr<0b1, iname, params>,
462 let Inst{22} = Vd{4};
463 let Inst{19-16} = Vn{3-0};
464 let Inst{15-12} = Vd{3-0};
467 let Inst{3-0} = Vm{3-0};
470 // Register operands for VCX* instructions
471 class CDE_VCX_RegisterOperandsTemplate<RegisterClass regclass>
472 : CDE_RegisterOperands {
473 let Rd = (outs regclass:$Vd);
474 let Rd_src = (ins regclass:$Vd_src);
475 let Rn = (ins regclass:$Vn);
476 let Rm = (ins regclass:$Vm);
479 class CDE_VCXQ_RegisterOperandsTemplate<RegisterClass regclass>
480 : CDE_RegisterOperands {
481 let Rd = (outs regclass:$Qd);
482 let Rd_src = (ins regclass:$Qd_src);
483 let Rn = (ins regclass:$Qn);
484 let Rm = (ins regclass:$Qm);
487 def cde_vcx_s_regs : CDE_VCX_RegisterOperandsTemplate<SPR>;
488 def cde_vcx_d_regs : CDE_VCX_RegisterOperandsTemplate<DPR_VFP2>;
489 def cde_vcx_q_regs : CDE_VCXQ_RegisterOperandsTemplate<MQPR>;
491 class CDE_VCX_ParamsTemplate<bit acc, CDE_RegisterOperands ops>
494 dag IOpsPrefix = !if(acc, ops.Rd_src, (ins));
497 let Iops1 = IOpsPrefix;
498 let Iops2 = !con(IOpsPrefix, ops.Rm);
499 let Iops3 = !con(IOpsPrefix, ops.Rn, ops.Rm);
500 let Cstr = !if(acc, "$Vd = $Vd_src", "");
504 class CDE_VCXQ_ParamsTemplate<bit acc, CDE_RegisterOperands ops>
507 dag IOpsPrefix = !if(acc, ops.Rd_src, (ins));
510 let Iops1 = IOpsPrefix;
511 let Iops2 = !con(IOpsPrefix, ops.Rm);
512 let Iops3 = !con(IOpsPrefix, ops.Rn, ops.Rm);
513 let Cstr = !if(acc, "$Qd = $Qd_src", "");
515 let Vpred = !if(acc, vpred_n, vpred_r);
518 def cde_vcx_params_s_noacc : CDE_VCX_ParamsTemplate<0b0, cde_vcx_s_regs>;
519 def cde_vcx_params_s_acc : CDE_VCX_ParamsTemplate<0b1, cde_vcx_s_regs>;
520 def cde_vcx_params_d_noacc : CDE_VCX_ParamsTemplate<0b0, cde_vcx_d_regs>;
521 def cde_vcx_params_d_acc : CDE_VCX_ParamsTemplate<0b1, cde_vcx_d_regs>;
522 def cde_vcx_params_q_noacc : CDE_VCXQ_ParamsTemplate<0b0, cde_vcx_q_regs>;
523 def cde_vcx_params_q_acc : CDE_VCXQ_ParamsTemplate<0b1, cde_vcx_q_regs>;
525 def CDE_VCX1_fpsp : CDE_VCX1_FP_Instr_S<"vcx1", cde_vcx_params_s_noacc>;
526 def CDE_VCX1A_fpsp : CDE_VCX1_FP_Instr_S<"vcx1a", cde_vcx_params_s_acc>;
527 def CDE_VCX1_fpdp : CDE_VCX1_FP_Instr_D<"vcx1", cde_vcx_params_d_noacc>;
528 def CDE_VCX1A_fpdp : CDE_VCX1_FP_Instr_D<"vcx1a", cde_vcx_params_d_acc>;
529 def CDE_VCX1_vec : CDE_VCX1_Vec_Instr<"vcx1", cde_vcx_params_q_noacc>;
530 def CDE_VCX1A_vec : CDE_VCX1_Vec_Instr<"vcx1a", cde_vcx_params_q_acc>;
532 def CDE_VCX2_fpsp : CDE_VCX2_FP_Instr_S<"vcx2", cde_vcx_params_s_noacc>;
533 def CDE_VCX2A_fpsp : CDE_VCX2_FP_Instr_S<"vcx2a", cde_vcx_params_s_acc>;
534 def CDE_VCX2_fpdp : CDE_VCX2_FP_Instr_D<"vcx2", cde_vcx_params_d_noacc>;
535 def CDE_VCX2A_fpdp : CDE_VCX2_FP_Instr_D<"vcx2a", cde_vcx_params_d_acc>;
536 def CDE_VCX2_vec : CDE_VCX2_Vec_Instr<"vcx2", cde_vcx_params_q_noacc>;
537 def CDE_VCX2A_vec : CDE_VCX2_Vec_Instr<"vcx2a", cde_vcx_params_q_acc>;
539 def CDE_VCX3_fpsp : CDE_VCX3_FP_Instr_S<"vcx3", cde_vcx_params_s_noacc>;
540 def CDE_VCX3A_fpsp : CDE_VCX3_FP_Instr_S<"vcx3a", cde_vcx_params_s_acc>;
541 def CDE_VCX3_fpdp : CDE_VCX3_FP_Instr_D<"vcx3", cde_vcx_params_d_noacc>;
542 def CDE_VCX3A_fpdp : CDE_VCX3_FP_Instr_D<"vcx3a", cde_vcx_params_d_acc>;
543 def CDE_VCX3_vec : CDE_VCX3_Vec_Instr<"vcx3", cde_vcx_params_q_noacc>;
544 def CDE_VCX3A_vec : CDE_VCX3_Vec_Instr<"vcx3a", cde_vcx_params_q_acc>;
547 let Predicates = [HasCDE, HasFPRegs] in {
548 def : Pat<(f32 (int_arm_cde_vcx1 timm:$coproc, timm:$imm)),
549 (f32 (CDE_VCX1_fpsp p_imm:$coproc, imm_11b:$imm))>;
550 def : Pat<(f32 (int_arm_cde_vcx1a timm:$coproc, (f32 SPR:$acc), timm:$imm)),
551 (f32 (CDE_VCX1A_fpsp p_imm:$coproc, SPR:$acc, imm_11b:$imm))>;
552 def : Pat<(f64 (int_arm_cde_vcx1 timm:$coproc, timm:$imm)),
553 (f64 (CDE_VCX1_fpdp p_imm:$coproc, imm_11b:$imm))>;
554 def : Pat<(f64 (int_arm_cde_vcx1a timm:$coproc, (f64 DPR:$acc), timm:$imm)),
555 (f64 (CDE_VCX1A_fpdp p_imm:$coproc, DPR:$acc, imm_11b:$imm))>;
557 def : Pat<(f32 (int_arm_cde_vcx2 timm:$coproc, (f32 SPR:$n), timm:$imm)),
558 (f32 (CDE_VCX2_fpsp p_imm:$coproc, SPR:$n, imm_6b:$imm))>;
559 def : Pat<(f32 (int_arm_cde_vcx2a timm:$coproc, (f32 SPR:$acc), (f32 SPR:$n),
561 (f32 (CDE_VCX2A_fpsp p_imm:$coproc, SPR:$acc, SPR:$n, imm_6b:$imm))>;
562 def : Pat<(f64 (int_arm_cde_vcx2 timm:$coproc, (f64 DPR:$n), timm:$imm)),
563 (f64 (CDE_VCX2_fpdp p_imm:$coproc, DPR:$n, imm_6b:$imm))>;
564 def : Pat<(f64 (int_arm_cde_vcx2a timm:$coproc, (f64 DPR:$acc), (f64 DPR:$n),
566 (f64 (CDE_VCX2A_fpdp p_imm:$coproc, DPR:$acc, DPR:$n, imm_6b:$imm))>;
568 def : Pat<(f32 (int_arm_cde_vcx3 timm:$coproc, (f32 SPR:$n), (f32 SPR:$m),
570 (f32 (CDE_VCX3_fpsp p_imm:$coproc, (f32 SPR:$n), (f32 SPR:$m),
572 def : Pat<(f32 (int_arm_cde_vcx3a timm:$coproc, (f32 SPR:$acc), (f32 SPR:$n),
573 (f32 SPR:$m), timm:$imm)),
574 (f32 (CDE_VCX3A_fpsp p_imm:$coproc, SPR:$acc, SPR:$n, SPR:$m,
576 def : Pat<(f64 (int_arm_cde_vcx3 timm:$coproc, (f64 DPR:$n), (f64 DPR:$m),
578 (f64 (CDE_VCX3_fpdp p_imm:$coproc, DPR:$n, DPR:$m, imm_3b:$imm))>;
579 def : Pat<(f64 (int_arm_cde_vcx3a timm:$coproc, (f64 DPR:$acc), (f64 DPR:$n),
580 (f64 DPR:$m), timm:$imm)),
581 (f64 (CDE_VCX3A_fpdp p_imm:$coproc, DPR:$acc, DPR:$n, DPR:$m,
585 let Predicates = [HasCDE, HasMVEInt] in {
586 def : Pat<(v16i8 (int_arm_cde_vcx1q timm:$coproc, timm:$imm)),
587 (v16i8 (CDE_VCX1_vec p_imm:$coproc, imm_12b:$imm))>;
588 def : Pat<(v16i8 (int_arm_cde_vcx1qa timm:$coproc, (v16i8 MQPR:$acc),
590 (v16i8 (CDE_VCX1A_vec p_imm:$coproc, MQPR:$acc, imm_12b:$imm))>;
592 def : Pat<(v16i8 (int_arm_cde_vcx2q timm:$coproc, (v16i8 MQPR:$n), timm:$imm)),
593 (v16i8 (CDE_VCX2_vec p_imm:$coproc, MQPR:$n, imm_7b:$imm))>;
594 def : Pat<(v16i8 (int_arm_cde_vcx2qa timm:$coproc, (v16i8 MQPR:$acc),
595 (v16i8 MQPR:$n), timm:$imm)),
596 (v16i8 (CDE_VCX2A_vec p_imm:$coproc, MQPR:$acc, MQPR:$n,
599 def : Pat<(v16i8 (int_arm_cde_vcx3q timm:$coproc, (v16i8 MQPR:$n),
600 (v16i8 MQPR:$m), timm:$imm)),
601 (v16i8 (CDE_VCX3_vec p_imm:$coproc, MQPR:$n, MQPR:$m,
603 def : Pat<(v16i8 (int_arm_cde_vcx3qa timm:$coproc, (v16i8 MQPR:$acc),
604 (v16i8 MQPR:$n), (v16i8 MQPR:$m),
606 (v16i8 (CDE_VCX3A_vec p_imm:$coproc, MQPR:$acc, MQPR:$n, MQPR:$m,
610 multiclass VCXPredicatedPat_m<MVEVectorVTInfo VTI> {
611 def : Pat<(VTI.Vec (int_arm_cde_vcx1q_predicated timm:$coproc,
612 (VTI.Vec MQPR:$inactive), timm:$imm,
613 (VTI.Pred VCCR:$pred))),
614 (VTI.Vec (CDE_VCX1_vec p_imm:$coproc, imm_12b:$imm, ARMVCCThen,
615 (VTI.Pred VCCR:$pred),
616 (VTI.Vec MQPR:$inactive)))>;
617 def : Pat<(VTI.Vec (int_arm_cde_vcx1qa_predicated timm:$coproc,
618 (VTI.Vec MQPR:$acc), timm:$imm,
619 (VTI.Pred VCCR:$pred))),
620 (VTI.Vec (CDE_VCX1A_vec p_imm:$coproc, (VTI.Vec MQPR:$acc),
621 imm_12b:$imm, ARMVCCThen,
622 (VTI.Pred VCCR:$pred)))>;
624 def : Pat<(VTI.Vec (int_arm_cde_vcx2q_predicated timm:$coproc,
625 (VTI.Vec MQPR:$inactive),
626 (v16i8 MQPR:$n), timm:$imm,
627 (VTI.Pred VCCR:$pred))),
628 (VTI.Vec (CDE_VCX2_vec p_imm:$coproc, (v16i8 MQPR:$n),
629 imm_7b:$imm, ARMVCCThen,
630 (VTI.Pred VCCR:$pred),
631 (VTI.Vec MQPR:$inactive)))>;
632 def : Pat<(VTI.Vec (int_arm_cde_vcx2qa_predicated timm:$coproc,
634 (v16i8 MQPR:$n), timm:$imm,
635 (VTI.Pred VCCR:$pred))),
636 (VTI.Vec (CDE_VCX2A_vec p_imm:$coproc, (VTI.Vec MQPR:$acc),
637 (v16i8 MQPR:$n), timm:$imm, ARMVCCThen,
638 (VTI.Pred VCCR:$pred)))>;
640 def : Pat<(VTI.Vec (int_arm_cde_vcx3q_predicated timm:$coproc,
641 (VTI.Vec MQPR:$inactive),
642 (v16i8 MQPR:$n), (v16i8 MQPR:$m),
644 (VTI.Pred VCCR:$pred))),
645 (VTI.Vec (CDE_VCX3_vec p_imm:$coproc, (v16i8 MQPR:$n),
647 imm_4b:$imm, ARMVCCThen,
648 (VTI.Pred VCCR:$pred),
649 (VTI.Vec MQPR:$inactive)))>;
650 def : Pat<(VTI.Vec (int_arm_cde_vcx3qa_predicated timm:$coproc,
652 (v16i8 MQPR:$n), (v16i8 MQPR:$m), timm:$imm,
653 (VTI.Pred VCCR:$pred))),
654 (VTI.Vec (CDE_VCX3A_vec p_imm:$coproc, (VTI.Vec MQPR:$acc),
655 (v16i8 MQPR:$n), (v16i8 MQPR:$m),
656 imm_4b:$imm, ARMVCCThen,
657 (VTI.Pred VCCR:$pred)))>;
660 let Predicates = [HasCDE, HasMVEInt] in
661 foreach VTI = [ MVE_v16i8, MVE_v8i16, MVE_v4i32, MVE_v2i64 ] in
662 defm : VCXPredicatedPat_m<VTI>;
664 let Predicates = [HasCDE, HasMVEFloat] in
665 foreach VTI = [ MVE_v8f16, MVE_v4f32 ] in
666 defm : VCXPredicatedPat_m<VTI>;