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
13// Immediate operand of arbitrary bit width
14class BitWidthImmOperand<int width>
15  : ImmAsmOperand<0, !add(!shl(1, width), -1)> {
16  let Name = "Imm"#width#"b";
17}
18
19class BitWidthImm<int width>
20  : Operand<i32>,
21    ImmLeaf<i32, "{ return Imm >= 0 && Imm < (1 << "#width#"); }"> {
22  let ParserMatchClass = BitWidthImmOperand<width>;
23}
24
25def CDEDualRegOp : RegisterOperand<GPRPairnosp, "printGPRPairOperand">;
26
27// Used by VCX3 FP
28def imm_3b : BitWidthImm<3>;
29
30// Used by VCX3 vector
31def imm_4b : BitWidthImm<4>;
32
33// Used by VCX2 FP and CX3
34def imm_6b :  BitWidthImm<6>;
35
36// Used by VCX2 vector
37def imm_7b :  BitWidthImm<7>;
38
39// Used by CX2
40def imm_9b :  BitWidthImm<9>;
41
42// Used by VCX1 FP
43def imm_11b : BitWidthImm<11>;
44
45// Used by VCX1 vector
46def imm_12b : BitWidthImm<12>;
47
48// Used by CX1
49def imm_13b : BitWidthImm<13>;
50
51// Base class for all CDE instructions
52class 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=*/[]>,
56    Sched<[]> {
57  bits<3> coproc;
58
59  let Inst{31-29} = 0b111;  // 15:13
60  let Inst{28} = acc;
61  let Inst{27-26} = 0b11;
62  let Inst{11} = 0b0;
63  let Inst{10-8} = coproc{2-0};
64
65  let isPredicable = 0;
66  let DecoderNamespace = "Thumb2CDE";
67}
68
69// Base class for CX* CDE instructions
70class CDE_GPR_Instr<bit dual, bit acc, dag oops, dag iops,
71                    string asm, string cstr>
72  : CDE_Instr<acc, oops, iops, asm, cstr>,
73    Requires<[HasCDE]> {
74
75  let Inst{25-24} = 0b10;
76  let Inst{6} = dual;
77  let isPredicable = acc;
78}
79
80// Set of registers used by the CDE instructions.
81class CDE_RegisterOperands {
82  dag Rd;
83  dag Rd_src;
84  dag Rn;
85  dag Rm;
86}
87
88// CX* CDE instruction parameter set
89class CX_Params {
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
99}
100
101// VCX* CDE instruction parameter set
102class VCX_Params {
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
110}
111
112// CX1, CX1A, CX1D, CX1DA
113class 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"),
117                  params.Cstr> {
118  bits<13> imm;
119  bits<4> Rd;
120
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};
126}
127
128// CX2, CX2A, CX2D, CX2DA
129class 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"),
133                  params.Cstr> {
134  bits<9> imm;
135  bits<4> Rd;
136  bits<4> Rn;
137
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};
144}
145
146// CX3, CX3A, CX3D, CX3DA
147class 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"),
151                  params.Cstr> {
152  bits<6> imm;
153  bits<4> Rd;
154  bits<4> Rn;
155  bits<4> Rm;
156
157  let Inst{23} = 0b1;
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};
164}
165
166// Registers for single-register variants of CX* instructions
167def 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);
172}
173
174// Registers for single-register variants of CX* instructions
175def 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);
180}
181
182class CDE_CX_ParamsTemplate<bit dual, bit acc, CDE_RegisterOperands ops>
183  : CX_Params {
184
185  dag IOpsPrefix = !if(acc, ops.Rd_src, (ins));
186
187  let Oops = ops.Rd;
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", "");
194  let Dual = dual;
195  let Acc = acc;
196}
197
198def cde_cx_params_single_noacc : CDE_CX_ParamsTemplate<0b0, 0b0, cde_cx_single_regs>;
199def cde_cx_params_single_acc   : CDE_CX_ParamsTemplate<0b0, 0b1, cde_cx_single_regs>;
200def cde_cx_params_dual_noacc   : CDE_CX_ParamsTemplate<0b1, 0b0, cde_cx_dual_regs>;
201def cde_cx_params_dual_acc     : CDE_CX_ParamsTemplate<0b1, 0b1, cde_cx_dual_regs>;
202
203def CDE_CX1   : CDE_CX1_Instr<"cx1",    cde_cx_params_single_noacc>;
204def CDE_CX1A  : CDE_CX1_Instr<"cx1a",   cde_cx_params_single_acc>;
205def CDE_CX1D  : CDE_CX1_Instr<"cx1d",   cde_cx_params_dual_noacc>;
206def CDE_CX1DA : CDE_CX1_Instr<"cx1da",  cde_cx_params_dual_acc>;
207
208def CDE_CX2   : CDE_CX2_Instr<"cx2",    cde_cx_params_single_noacc>;
209def CDE_CX2A  : CDE_CX2_Instr<"cx2a",   cde_cx_params_single_acc>;
210def CDE_CX2D  : CDE_CX2_Instr<"cx2d",   cde_cx_params_dual_noacc>;
211def CDE_CX2DA : CDE_CX2_Instr<"cx2da",  cde_cx_params_dual_acc>;
212
213def CDE_CX3   : CDE_CX3_Instr<"cx3",    cde_cx_params_single_noacc>;
214def CDE_CX3A  : CDE_CX3_Instr<"cx3a",   cde_cx_params_single_acc>;
215def CDE_CX3D  : CDE_CX3_Instr<"cx3d",   cde_cx_params_dual_noacc>;
216def CDE_CX3DA : CDE_CX3_Instr<"cx3da",  cde_cx_params_dual_acc>;
217
218let 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,
222                                   timm:$imm)),
223            (i32 (CDE_CX1A p_imm:$coproc, GPRwithAPSR_NZCVnosp:$acc,
224                           imm_13b:$imm))>;
225  def : Pat<(i32 (int_arm_cde_cx2 timm:$coproc, GPRwithAPSR_NZCVnosp:$n,
226                                  timm:$imm)),
227            (i32 (CDE_CX2 p_imm:$coproc, GPRwithAPSR_NZCVnosp:$n,
228                          imm_9b:$imm))>;
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))>;
245}
246
247class CDE_RequiresSReg : Requires<[HasCDE, HasFPRegs]>;
248class CDE_RequiresDReg : Requires<[HasCDE, HasFPRegs]>;
249class CDE_RequiresQReg : Requires<[HasCDE, HasMVEInt]>;
250
251// Base class for CDE VCX* instructions
252class CDE_FP_Vec_Instr<bit vec, bit acc, dag oops, dag iops, string asm, string cstr>
253  : CDE_Instr<acc, oops, iops, asm, cstr> {
254  let Inst{25} = 0b0;
255  let Inst{6} = vec;
256}
257
258// Base class for floating-point variants of CDE VCX* instructions
259class 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> {
261  let Inst{24} = sz;
262}
263
264// Base class for vector variants of CDE VCX* instruction
265class CDE_Vec_Instr<bit acc, dag oops, dag iops, string asm, string cstr,
266                    vpred_ops vpred>
267  : CDE_FP_Vec_Instr<0b1, acc, oops,
268                     !con(iops, (ins vpred:$vp)), asm,
269                     !strconcat(cstr, vpred.vpred_constraint)>,
270    CDE_RequiresQReg {
271}
272
273
274// VCX1/VCX1A, vector variant
275class 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> {
279  bits<12> imm;
280  bits<3> Qd;
281
282  let Inst{24} = imm{11};
283  let Inst{23} = 0b0;
284  let Inst{22} = 0b0;
285  let Inst{21-20} = 0b10;
286  let Inst{19-16} = imm{10-7};
287  let Inst{15-13} = Qd{2-0};
288  let Inst{12} = 0b0;
289  let Inst{7} = imm{6};
290  let Inst{5-0} = imm{5-0};
291
292  let Unpredictable{22} = 0b1;
293}
294
295// VCX1/VCX1A, base class for FP variants
296class 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> {
300  bits<11> imm;
301
302  let Inst{23} = 0b0;
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};
307}
308
309// VCX1/VCX1A, S registers
310class CDE_VCX1_FP_Instr_S<string iname, VCX_Params params>
311  : CDE_VCX1_FP_Instr<0b0, iname, params>,
312    CDE_RequiresSReg {
313  bits<5> Vd;
314
315  let Inst{22} = Vd{0};
316  let Inst{15-12} = Vd{4-1};
317}
318
319// VCX1/VCX1A, D registers
320class CDE_VCX1_FP_Instr_D<string iname, VCX_Params params>
321  : CDE_VCX1_FP_Instr<0b1, iname, params>,
322    CDE_RequiresDReg {
323  bits<5> Vd;
324
325  let Inst{22} = Vd{4};
326  let Inst{15-12} = Vd{3-0};
327}
328
329// VCX2/VCX2A, vector variant
330class 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,
334                 params.Vpred> {
335  bits<7> imm;
336  bits<3> Qd;
337  bits<3> Qm;
338
339  let Inst{24} = imm{6};
340  let Inst{23} = 0b0;
341  let Inst{22} = 0b0;
342  let Inst{21-20} = 0b11;
343  let Inst{19-16} = imm{5-2};
344  let Inst{15-13} = Qd{2-0};
345  let Inst{12} = 0b0;
346  let Inst{7} = imm{1};
347  let Inst{5} = 0b0;
348  let Inst{4} = imm{0};
349  let Inst{3-1} = Qm{2-0};
350  let Inst{0} = 0b0;
351
352  let Unpredictable{22} = 0b1;
353  let Unpredictable{5} = 0b1;
354}
355
356// VCX2/VCX2A, base class for FP variants
357class 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> {
361  bits<6> imm;
362
363  let Inst{23} = 0b0;
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};
368}
369
370// VCX2/VCX2A, S registers
371class CDE_VCX2_FP_Instr_S<string iname, VCX_Params params>
372  : CDE_VCX2_FP_Instr<0b0, iname, params>,
373    CDE_RequiresSReg {
374  bits<5> Vd;
375  bits<5> Vm;
376
377  let Inst{15-12} = Vd{4-1};
378  let Inst{22} = Vd{0};
379  let Inst{3-0} = Vm{4-1};
380  let Inst{5} = Vm{0};
381}
382
383// VCX2/VCX2A, D registers
384class CDE_VCX2_FP_Instr_D<string iname, VCX_Params params>
385  : CDE_VCX2_FP_Instr<0b1, iname, params>,
386    CDE_RequiresDReg {
387  bits<5> Vd;
388  bits<5> Vm;
389
390  let Inst{15-12} = Vd{3-0};
391  let Inst{22} = Vd{4};
392  let Inst{3-0} = Vm{3-0};
393  let Inst{5} = Vm{4};
394}
395
396// VCX3/VCX3A, vector variant
397class 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,
401                 params.Vpred> {
402  bits<4> imm;
403  bits<3> Qd;
404  bits<3> Qm;
405  bits<3> Qn;
406
407  let Inst{24} = imm{3};
408  let Inst{23} = 0b1;
409  let Inst{22} = 0b0;
410  let Inst{21-20} = imm{2-1};
411  let Inst{19-17} = Qn{2-0};
412  let Inst{16} = 0b0;
413  let Inst{15-13} = Qd{2-0};
414  let Inst{12} = 0b0;
415  let Inst{7} = 0b0;
416  let Inst{5} = 0b0;
417  let Inst{4} = imm{0};
418  let Inst{3-1} = Qm{2-0};
419  let Inst{0} = 0b0;
420
421  let Unpredictable{22} = 0b1;
422  let Unpredictable{7} = 0b1;
423  let Unpredictable{5} = 0b1;
424}
425
426// VCX3/VCX3A, base class for FP variants
427class 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> {
431  bits<3> imm;
432
433  let Inst{23} = 0b1;
434  let Inst{21-20} = imm{2-1};
435  let Inst{4} = imm{0};
436}
437
438// VCX3/VCX3A, S registers
439class CDE_VCX3_FP_Instr_S<string iname, VCX_Params params>
440  : CDE_VCX3_FP_Instr<0b0, iname, params>,
441    CDE_RequiresSReg {
442  bits<5> Vd;
443  bits<5> Vm;
444  bits<5> Vn;
445
446  let Inst{22} = Vd{0};
447  let Inst{19-16} = Vn{4-1};
448  let Inst{15-12} = Vd{4-1};
449  let Inst{7} = Vn{0};
450  let Inst{5} = Vm{0};
451  let Inst{3-0} = Vm{4-1};
452}
453
454// VCX3/VCX3A, D registers
455class CDE_VCX3_FP_Instr_D<string iname, VCX_Params params>
456  : CDE_VCX3_FP_Instr<0b1, iname, params>,
457    CDE_RequiresDReg {
458  bits<5> Vd;
459  bits<5> Vm;
460  bits<5> Vn;
461
462  let Inst{22} = Vd{4};
463  let Inst{19-16} = Vn{3-0};
464  let Inst{15-12} = Vd{3-0};
465  let Inst{7} = Vn{4};
466  let Inst{5} = Vm{4};
467  let Inst{3-0} = Vm{3-0};
468}
469
470// Register operands for VCX* instructions
471class 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);
477}
478
479class 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);
485}
486
487def cde_vcx_s_regs : CDE_VCX_RegisterOperandsTemplate<SPR>;
488def cde_vcx_d_regs : CDE_VCX_RegisterOperandsTemplate<DPR_VFP2>;
489def cde_vcx_q_regs : CDE_VCXQ_RegisterOperandsTemplate<MQPR>;
490
491class CDE_VCX_ParamsTemplate<bit acc, CDE_RegisterOperands ops>
492  : VCX_Params {
493
494  dag IOpsPrefix = !if(acc, ops.Rd_src, (ins));
495
496  let Oops = ops.Rd;
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", "");
501  let Acc = acc;
502}
503
504class CDE_VCXQ_ParamsTemplate<bit acc, CDE_RegisterOperands ops>
505  : VCX_Params {
506
507  dag IOpsPrefix = !if(acc, ops.Rd_src, (ins));
508
509  let Oops = ops.Rd;
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", "");
514  let Acc = acc;
515  let Vpred = !if(acc, vpred_n, vpred_r);
516}
517
518def cde_vcx_params_s_noacc : CDE_VCX_ParamsTemplate<0b0, cde_vcx_s_regs>;
519def cde_vcx_params_s_acc   : CDE_VCX_ParamsTemplate<0b1, cde_vcx_s_regs>;
520def cde_vcx_params_d_noacc : CDE_VCX_ParamsTemplate<0b0, cde_vcx_d_regs>;
521def cde_vcx_params_d_acc   : CDE_VCX_ParamsTemplate<0b1, cde_vcx_d_regs>;
522def cde_vcx_params_q_noacc : CDE_VCXQ_ParamsTemplate<0b0, cde_vcx_q_regs>;
523def cde_vcx_params_q_acc   : CDE_VCXQ_ParamsTemplate<0b1, cde_vcx_q_regs>;
524
525def CDE_VCX1_fpsp   : CDE_VCX1_FP_Instr_S<"vcx1",  cde_vcx_params_s_noacc>;
526def CDE_VCX1A_fpsp  : CDE_VCX1_FP_Instr_S<"vcx1a", cde_vcx_params_s_acc>;
527def CDE_VCX1_fpdp   : CDE_VCX1_FP_Instr_D<"vcx1",  cde_vcx_params_d_noacc>;
528def CDE_VCX1A_fpdp  : CDE_VCX1_FP_Instr_D<"vcx1a", cde_vcx_params_d_acc>;
529def CDE_VCX1_vec    : CDE_VCX1_Vec_Instr<"vcx1",   cde_vcx_params_q_noacc>;
530def CDE_VCX1A_vec   : CDE_VCX1_Vec_Instr<"vcx1a",  cde_vcx_params_q_acc>;
531
532def CDE_VCX2_fpsp   : CDE_VCX2_FP_Instr_S<"vcx2",  cde_vcx_params_s_noacc>;
533def CDE_VCX2A_fpsp  : CDE_VCX2_FP_Instr_S<"vcx2a", cde_vcx_params_s_acc>;
534def CDE_VCX2_fpdp   : CDE_VCX2_FP_Instr_D<"vcx2",  cde_vcx_params_d_noacc>;
535def CDE_VCX2A_fpdp  : CDE_VCX2_FP_Instr_D<"vcx2a", cde_vcx_params_d_acc>;
536def CDE_VCX2_vec    : CDE_VCX2_Vec_Instr<"vcx2",   cde_vcx_params_q_noacc>;
537def CDE_VCX2A_vec   : CDE_VCX2_Vec_Instr<"vcx2a",  cde_vcx_params_q_acc>;
538
539def CDE_VCX3_fpsp   : CDE_VCX3_FP_Instr_S<"vcx3",  cde_vcx_params_s_noacc>;
540def CDE_VCX3A_fpsp  : CDE_VCX3_FP_Instr_S<"vcx3a", cde_vcx_params_s_acc>;
541def CDE_VCX3_fpdp   : CDE_VCX3_FP_Instr_D<"vcx3",  cde_vcx_params_d_noacc>;
542def CDE_VCX3A_fpdp  : CDE_VCX3_FP_Instr_D<"vcx3a", cde_vcx_params_d_acc>;
543def CDE_VCX3_vec    : CDE_VCX3_Vec_Instr<"vcx3",   cde_vcx_params_q_noacc>;
544def CDE_VCX3A_vec   : CDE_VCX3_Vec_Instr<"vcx3a",  cde_vcx_params_q_acc>;
545
546
547let 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))>;
556
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),
560                                    timm:$imm)),
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),
565                                    timm:$imm)),
566            (f64 (CDE_VCX2A_fpdp p_imm:$coproc, DPR:$acc, DPR:$n, imm_6b:$imm))>;
567
568  def : Pat<(f32 (int_arm_cde_vcx3 timm:$coproc, (f32 SPR:$n), (f32 SPR:$m),
569                                   timm:$imm)),
570            (f32 (CDE_VCX3_fpsp p_imm:$coproc, (f32 SPR:$n), (f32 SPR:$m),
571                                imm_3b:$imm))>;
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,
575                                 imm_3b:$imm))>;
576  def : Pat<(f64 (int_arm_cde_vcx3 timm:$coproc, (f64 DPR:$n), (f64 DPR:$m),
577                                   timm:$imm)),
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,
582                                 imm_3b:$imm))>;
583}
584
585let 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),
589                                       timm:$imm)),
590            (v16i8 (CDE_VCX1A_vec p_imm:$coproc, MQPR:$acc, imm_12b:$imm))>;
591
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,
597                                  imm_7b:$imm))>;
598
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,
602                                 imm_4b:$imm))>;
603  def : Pat<(v16i8 (int_arm_cde_vcx3qa timm:$coproc, (v16i8 MQPR:$acc),
604                                       (v16i8 MQPR:$n), (v16i8 MQPR:$m),
605                                       timm:$imm)),
606            (v16i8 (CDE_VCX3A_vec p_imm:$coproc, MQPR:$acc, MQPR:$n, MQPR:$m,
607                                  imm_4b:$imm))>;
608}
609
610multiclass 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), zero_reg,
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), zero_reg))>;
623
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), zero_reg,
631                                    (VTI.Vec MQPR:$inactive)))>;
632  def : Pat<(VTI.Vec (int_arm_cde_vcx2qa_predicated timm:$coproc,
633                                    (VTI.Vec MQPR:$acc),
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), zero_reg))>;
639
640  def : Pat<(VTI.Vec (int_arm_cde_vcx3q_predicated timm:$coproc,
641                                    (VTI.Vec MQPR:$inactive),
642                                    (v16i8 MQPR:$n), (v16i8 MQPR:$m),
643                                    timm:$imm,
644                                    (VTI.Pred VCCR:$pred))),
645            (VTI.Vec (CDE_VCX3_vec p_imm:$coproc, (v16i8 MQPR:$n),
646                                    (v16i8 MQPR:$m),
647                                    imm_4b:$imm, ARMVCCThen,
648                                    (VTI.Pred VCCR:$pred), zero_reg,
649                                    (VTI.Vec MQPR:$inactive)))>;
650  def : Pat<(VTI.Vec (int_arm_cde_vcx3qa_predicated timm:$coproc,
651                                    (VTI.Vec MQPR:$acc),
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), zero_reg))>;
658}
659
660let Predicates = [HasCDE, HasMVEInt] in
661  foreach VTI = [ MVE_v16i8, MVE_v8i16, MVE_v4i32, MVE_v2i64 ] in
662    defm : VCXPredicatedPat_m<VTI>;
663
664let Predicates = [HasCDE, HasMVEFloat] in
665  foreach VTI = [ MVE_v8f16, MVE_v4f32 ] in
666    defm : VCXPredicatedPat_m<VTI>;
667