]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/Target/ARM/ARMInstrCDE.td
Import tzdata 2020c
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / Target / ARM / ARMInstrCDE.td
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
14 class BitWidthImmOperand<int width>
15   : ImmAsmOperand<0, !add(!shl(1, width), -1)> {
16   let Name = "Imm"#width#"b";
17 }
18
19 class BitWidthImm<int width>
20   : Operand<i32>,
21     ImmLeaf<i32, "{ return Imm >= 0 && Imm < (1 << "#width#"); }"> {
22   let ParserMatchClass = BitWidthImmOperand<width>;
23 }
24
25 def CDEDualRegOp : RegisterOperand<GPRPairnosp, "printGPRPairOperand">;
26
27 // Used by VCX3 FP
28 def imm_3b : BitWidthImm<3>;
29
30 // Used by VCX3 vector
31 def imm_4b : BitWidthImm<4>;
32
33 // Used by VCX2 FP and CX3
34 def imm_6b :  BitWidthImm<6>;
35
36 // Used by VCX2 vector
37 def imm_7b :  BitWidthImm<7>;
38
39 // Used by CX2
40 def imm_9b :  BitWidthImm<9>;
41
42 // Used by VCX1 FP
43 def imm_11b : BitWidthImm<11>;
44
45 // Used by VCX1 vector
46 def imm_12b : BitWidthImm<12>;
47
48 // Used by CX1
49 def imm_13b : BitWidthImm<13>;
50
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=*/[]>,
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
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>,
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.
81 class CDE_RegisterOperands {
82   dag Rd;
83   dag Rd_src;
84   dag Rn;
85   dag Rm;
86 }
87
88 // CX* CDE instruction parameter set
89 class 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
102 class 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
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"),
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
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"),
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
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"),
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
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);
172 }
173
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);
180 }
181
182 class 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
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>;
202
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>;
207
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>;
212
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>;
217
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,
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
247 class CDE_RequiresSReg : Requires<[HasCDE, HasFPRegs]>;
248 class CDE_RequiresDReg : Requires<[HasCDE, HasFPRegs]>;
249 class CDE_RequiresQReg : Requires<[HasCDE, HasMVEInt]>;
250
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> {
254   let Inst{25} = 0b0;
255   let Inst{6} = vec;
256 }
257
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> {
261   let Inst{24} = sz;
262 }
263
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,
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
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> {
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
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> {
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
310 class 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
320 class 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
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,
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
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> {
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
371 class 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
384 class 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
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,
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
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> {
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
439 class 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
455 class 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
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);
477 }
478
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);
485 }
486
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>;
490
491 class 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
504 class 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
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>;
524
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>;
531
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>;
538
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>;
545
546
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))>;
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
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),
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
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)))>;
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),
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)))>;
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),
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)))>;
658 }
659
660 let Predicates = [HasCDE, HasMVEInt] in
661   foreach VTI = [ MVE_v16i8, MVE_v8i16, MVE_v4i32, MVE_v2i64 ] in
662     defm : VCXPredicatedPat_m<VTI>;
663
664 let Predicates = [HasCDE, HasMVEFloat] in
665   foreach VTI = [ MVE_v8f16, MVE_v4f32 ] in
666     defm : VCXPredicatedPat_m<VTI>;