1//=- HexagonInstrInfoV60.td - Target Desc. for Hexagon Target -*- tablegen -*-=//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file describes the Hexagon V60 instructions in TableGen format.
11//
12//===----------------------------------------------------------------------===//
13
14
15// Vector store
16let mayStore = 1, validSubTargets = HasV60SubT, hasSideEffects = 0 in
17{
18  class VSTInst<dag outs, dag ins, string asmstr, list<dag> pattern = [],
19                string cstr = "", InstrItinClass itin = CVI_VM_ST,
20                IType type = TypeCVI_VM_ST>
21  : InstHexagon<outs, ins, asmstr, pattern, cstr, itin, type>, OpcodeHexagon;
22
23}
24
25// Vector load
26let Predicates = [HasV60T, UseHVX] in
27let mayLoad = 1, validSubTargets = HasV60SubT, hasSideEffects = 0 in
28  class V6_LDInst<dag outs, dag ins, string asmstr, list<dag> pattern = [],
29                  string cstr = "", InstrItinClass itin = CVI_VM_LD,
30                  IType type = TypeCVI_VM_LD>
31  : InstHexagon<outs, ins, asmstr, pattern, cstr, itin, type>;
32
33let Predicates = [HasV60T, UseHVX] in
34let mayStore = 1, validSubTargets = HasV60SubT, hasSideEffects = 0 in
35class V6_STInst<dag outs, dag ins, string asmstr, list<dag> pattern = [],
36                string cstr = "", InstrItinClass itin = CVI_VM_ST,
37                IType type = TypeCVI_VM_ST>
38: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, type>;
39
40//===----------------------------------------------------------------------===//
41// Vector loads with base + immediate offset
42//===----------------------------------------------------------------------===//
43let addrMode = BaseImmOffset, accessSize = Vector64Access in
44class T_vload_ai<string asmStr>
45  : V6_LDInst <(outs VectorRegs:$dst), (ins IntRegs:$src1, s4_6Imm:$src2),
46                asmStr>;
47
48let isCodeGenOnly = 1, addrMode = BaseImmOffset, accessSize = Vector128Access in
49class T_vload_ai_128B<string asmStr>
50  : V6_LDInst <(outs VectorRegs128B:$dst), (ins IntRegs:$src1, s4_7Imm:$src2),
51                asmStr>;
52
53let isCVLoadable = 1, hasNewValue = 1 in {
54  def V6_vL32b_ai         : T_vload_ai <"$dst = vmem($src1+#$src2)">,
55                            V6_vL32b_ai_enc;
56  def V6_vL32b_nt_ai      : T_vload_ai <"$dst = vmem($src1+#$src2):nt">,
57                            V6_vL32b_nt_ai_enc;
58  // 128B
59  def V6_vL32b_ai_128B    : T_vload_ai_128B <"$dst = vmem($src1+#$src2)">,
60                            V6_vL32b_ai_128B_enc;
61  def V6_vL32b_nt_ai_128B : T_vload_ai_128B <"$dst = vmem($src1+#$src2):nt">,
62                            V6_vL32b_nt_ai_128B_enc;
63}
64
65let Itinerary = CVI_VM_VP_LDU, Type = TypeCVI_VM_VP_LDU, hasNewValue = 1 in {
66  def V6_vL32Ub_ai      : T_vload_ai <"$dst = vmemu($src1+#$src2)">,
67                          V6_vL32Ub_ai_enc;
68  def V6_vL32Ub_ai_128B : T_vload_ai_128B <"$dst = vmemu($src1+#$src2)">,
69                          V6_vL32Ub_ai_128B_enc;
70}
71
72let Itinerary = CVI_VM_LD, Type = TypeCVI_VM_LD, isCVLoad = 1,
73    hasNewValue = 1 in {
74  def V6_vL32b_cur_ai    : T_vload_ai <"$dst.cur = vmem($src1+#$src2)">,
75                           V6_vL32b_cur_ai_enc;
76  def V6_vL32b_nt_cur_ai : T_vload_ai <"$dst.cur = vmem($src1+#$src2):nt">,
77                           V6_vL32b_nt_cur_ai_enc;
78  // 128B
79  def V6_vL32b_cur_ai_128B    : T_vload_ai_128B
80                                <"$dst.cur = vmem($src1+#$src2)">,
81                                V6_vL32b_cur_ai_128B_enc;
82  def V6_vL32b_nt_cur_ai_128B : T_vload_ai_128B
83                                <"$dst.cur = vmem($src1+#$src2):nt">,
84                                V6_vL32b_nt_cur_ai_128B_enc;
85}
86
87
88let Itinerary = CVI_VM_TMP_LD, Type = TypeCVI_VM_TMP_LD, hasNewValue = 1 in {
89  def V6_vL32b_tmp_ai    : T_vload_ai <"$dst.tmp = vmem($src1+#$src2)">,
90                           V6_vL32b_tmp_ai_enc;
91  def V6_vL32b_nt_tmp_ai : T_vload_ai <"$dst.tmp = vmem($src1+#$src2):nt">,
92                           V6_vL32b_nt_tmp_ai_enc;
93  // 128B
94  def V6_vL32b_tmp_ai_128B    : T_vload_ai_128B
95                                <"$dst.tmp = vmem($src1+#$src2)">,
96                                V6_vL32b_tmp_ai_128B_enc;
97  def V6_vL32b_nt_tmp_ai_128B : T_vload_ai_128B
98                                <"$dst.tmp = vmem($src1+#$src2)">,
99                                V6_vL32b_nt_tmp_ai_128B_enc;
100}
101
102//===----------------------------------------------------------------------===//
103// Vector stores with base + immediate offset - unconditional
104//===----------------------------------------------------------------------===//
105let addrMode = BaseImmOffset, accessSize = Vector64Access in
106class T_vstore_ai <string mnemonic, string baseOp, Operand ImmOp,
107                   RegisterClass RC, bit isNT>
108  : V6_STInst <(outs), (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
109    mnemonic#"($src1+#$src2)"#!if(isNT, ":nt", "")#" = $src3">, NewValueRel {
110  let BaseOpcode = baseOp;
111}
112
113let accessSize = Vector64Access in
114class T_vstore_ai_64B <string mnemonic, string baseOp, bit isNT = 0>
115  : T_vstore_ai <mnemonic, baseOp, s4_6Imm, VectorRegs, isNT>;
116
117let isCodeGenOnly = 1, accessSize = Vector128Access in
118class T_vstore_ai_128B <string mnemonic, string baseOp, bit isNT = 0>
119  : T_vstore_ai <mnemonic, baseOp#"128B", s4_7Imm, VectorRegs128B, isNT>;
120
121let isNVStorable = 1 in {
122  def V6_vS32b_ai         : T_vstore_ai_64B <"vmem", "vS32b_ai">,
123                            V6_vS32b_ai_enc;
124  def V6_vS32b_ai_128B    : T_vstore_ai_128B <"vmem", "vS32b_ai">,
125                            V6_vS32b_ai_128B_enc;
126}
127
128let isNVStorable = 1, isNonTemporal = 1 in {
129  def V6_vS32b_nt_ai      : T_vstore_ai_64B <"vmem", "vS32b_ai", 1>,
130                            V6_vS32b_nt_ai_enc;
131  def V6_vS32b_nt_ai_128B : T_vstore_ai_128B <"vmem", "vS32b_ai", 1>,
132                            V6_vS32b_nt_ai_128B_enc;
133}
134
135let Itinerary = CVI_VM_STU, Type = TypeCVI_VM_STU in {
136  def V6_vS32Ub_ai      : T_vstore_ai_64B <"vmemu", "vs32Ub_ai">,
137                          V6_vS32Ub_ai_enc;
138  def V6_vS32Ub_ai_128B : T_vstore_ai_128B <"vmemu", "vs32Ub_ai">,
139                          V6_vS32Ub_ai_128B_enc;
140}
141//===----------------------------------------------------------------------===//
142// Vector stores with base + immediate offset - unconditional new
143//===----------------------------------------------------------------------===//
144let addrMode = BaseImmOffset, isNewValue = 1, opNewValue = 2, isNVStore = 1,
145    Itinerary = CVI_VM_NEW_ST, Type = TypeCVI_VM_NEW_ST in
146class T_vstore_new_ai <string baseOp, Operand ImmOp, RegisterClass RC, bit isNT>
147  : V6_STInst <(outs ), (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
148    "vmem($src1+#$src2)"#!if(isNT, ":nt", "")#" = $src3.new">, NewValueRel {
149  let BaseOpcode = baseOp;
150}
151
152let accessSize = Vector64Access in
153class T_vstore_new_ai_64B <string baseOp, bit isNT = 0>
154  : T_vstore_new_ai <baseOp, s4_6Imm, VectorRegs, isNT>;
155
156let isCodeGenOnly = 1, accessSize = Vector128Access in
157class T_vstore_new_ai_128B <string baseOp, bit isNT = 0>
158  : T_vstore_new_ai <baseOp#"128B", s4_7Imm, VectorRegs128B, isNT>;
159
160def V6_vS32b_new_ai      : T_vstore_new_ai_64B <"vS32b_ai">, V6_vS32b_new_ai_enc;
161def V6_vS32b_new_ai_128B : T_vstore_new_ai_128B <"vS32b_ai">,
162                           V6_vS32b_new_ai_128B_enc;
163
164let isNonTemporal = 1 in {
165  def V6_vS32b_nt_new_ai      : T_vstore_new_ai_64B<"vS32b_ai", 1>,
166                                V6_vS32b_nt_new_ai_enc;
167  def V6_vS32b_nt_new_ai_128B : T_vstore_new_ai_128B<"vS32b_ai", 1>,
168                                V6_vS32b_nt_new_ai_128B_enc;
169}
170
171//===----------------------------------------------------------------------===//
172// Vector stores with base + immediate offset - conditional
173//===----------------------------------------------------------------------===//
174let addrMode = BaseImmOffset, isPredicated = 1 in
175class T_vstore_pred_ai <string mnemonic, string baseOp, Operand ImmOp,
176                        RegisterClass RC, bit isPredNot = 0, bit isNT = 0>
177  : V6_STInst <(outs),
178               (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$src3, RC:$src4),
179    "if ("#!if(isPredNot, "!", "")#"$src1) "
180     #mnemonic#"($src2+#$src3)"#!if(isNT, ":nt", "")#" = $src4">, NewValueRel {
181  let isPredicatedFalse = isPredNot;
182  let BaseOpcode = baseOp;
183}
184
185let accessSize = Vector64Access in
186class T_vstore_pred_ai_64B <string mnemonic, string baseOp,
187                            bit isPredNot = 0, bit isNT = 0>
188  : T_vstore_pred_ai <mnemonic, baseOp, s4_6Imm, VectorRegs, isPredNot, isNT>;
189
190let isCodeGenOnly = 1, accessSize = Vector128Access in
191class T_vstore_pred_ai_128B <string mnemonic, string baseOp,
192                             bit isPredNot = 0, bit isNT = 0>
193  : T_vstore_pred_ai <mnemonic, baseOp#"128B", s4_7Imm, VectorRegs128B,
194                      isPredNot, isNT>;
195
196let isNVStorable = 1 in {
197  def V6_vS32b_pred_ai     : T_vstore_pred_ai_64B <"vmem", "vS32b_ai">,
198                             V6_vS32b_pred_ai_enc;
199  def V6_vS32b_npred_ai    : T_vstore_pred_ai_64B <"vmem", "vS32b_ai", 1>,
200                             V6_vS32b_npred_ai_enc;
201  // 128B
202  def V6_vS32b_pred_ai_128B    : T_vstore_pred_ai_128B <"vmem", "vS32b_ai">,
203                                 V6_vS32b_pred_ai_128B_enc;
204  def V6_vS32b_npred_ai_128B   : T_vstore_pred_ai_128B <"vmem", "vS32b_ai", 1>,
205                                 V6_vS32b_npred_ai_128B_enc;
206}
207let isNVStorable = 1, isNonTemporal = 1 in {
208  def V6_vS32b_nt_pred_ai  : T_vstore_pred_ai_64B <"vmem", "vS32b_ai", 0, 1>,
209                             V6_vS32b_nt_pred_ai_enc;
210  def V6_vS32b_nt_npred_ai : T_vstore_pred_ai_64B <"vmem", "vS32b_ai", 1, 1>,
211                             V6_vS32b_nt_npred_ai_enc;
212  // 128B
213  def V6_vS32b_nt_pred_ai_128B  : T_vstore_pred_ai_128B
214                                  <"vmem", "vS32b_ai", 0, 1>,
215                                  V6_vS32b_nt_pred_ai_128B_enc;
216  def V6_vS32b_nt_npred_ai_128B : T_vstore_pred_ai_128B
217                                  <"vmem", "vS32b_ai", 1, 1>,
218                                  V6_vS32b_nt_npred_ai_128B_enc;
219}
220
221let Itinerary = CVI_VM_STU, Type = TypeCVI_VM_STU in {
222  def V6_vS32Ub_pred_ai  : T_vstore_pred_ai_64B <"vmemu", "vS32Ub_ai">,
223                           V6_vS32Ub_pred_ai_enc;
224  def V6_vS32Ub_npred_ai : T_vstore_pred_ai_64B <"vmemu", "vS32Ub_ai", 1>,
225                           V6_vS32Ub_npred_ai_enc;
226  // 128B
227  def V6_vS32Ub_pred_ai_128B  :T_vstore_pred_ai_128B <"vmemu", "vS32Ub_ai">,
228                               V6_vS32Ub_pred_ai_128B_enc;
229  def V6_vS32Ub_npred_ai_128B :T_vstore_pred_ai_128B <"vmemu", "vS32Ub_ai", 1>,
230                               V6_vS32Ub_npred_ai_128B_enc;
231}
232
233//===----------------------------------------------------------------------===//
234// Vector stores with base + immediate offset - byte-enabled aligned
235//===----------------------------------------------------------------------===//
236let addrMode = BaseImmOffset in
237class T_vstore_qpred_ai <Operand ImmOp, RegisterClass RC,
238                         bit isPredNot = 0, bit isNT = 0>
239  : V6_STInst <(outs),
240               (ins VecPredRegs:$src1, IntRegs:$src2, ImmOp:$src3, RC:$src4),
241    "if ("#!if(isPredNot, "!", "")#"$src1) vmem($src2+#$src3)"
242          #!if(isNT, ":nt", "")#" = $src4"> {
243  let isPredicatedFalse = isPredNot;
244}
245
246let accessSize = Vector64Access in
247class T_vstore_qpred_ai_64B <bit isPredNot = 0, bit isNT = 0>
248  : T_vstore_qpred_ai <s4_6Imm, VectorRegs, isPredNot, isNT>;
249
250let isCodeGenOnly = 1, accessSize = Vector128Access in
251class T_vstore_qpred_ai_128B <bit isPredNot = 0, bit isNT = 0>
252  : T_vstore_qpred_ai <s4_7Imm, VectorRegs128B, isPredNot, isNT>;
253
254def V6_vS32b_qpred_ai  : T_vstore_qpred_ai_64B, V6_vS32b_qpred_ai_enc;
255def V6_vS32b_nqpred_ai : T_vstore_qpred_ai_64B <1>,
256                         V6_vS32b_nqpred_ai_enc;
257def V6_vS32b_nt_qpred_ai  : T_vstore_qpred_ai_64B <0, 1>,
258                            V6_vS32b_nt_qpred_ai_enc;
259def V6_vS32b_nt_nqpred_ai : T_vstore_qpred_ai_64B <1, 1>,
260                            V6_vS32b_nt_nqpred_ai_enc;
261// 128B
262def V6_vS32b_qpred_ai_128B  : T_vstore_qpred_ai_128B, V6_vS32b_qpred_ai_128B_enc;
263def V6_vS32b_nqpred_ai_128B : T_vstore_qpred_ai_128B<1>,
264                              V6_vS32b_nqpred_ai_128B_enc;
265def V6_vS32b_nt_qpred_ai_128B  : T_vstore_qpred_ai_128B<0, 1>,
266                                 V6_vS32b_nt_qpred_ai_128B_enc;
267def V6_vS32b_nt_nqpred_ai_128B : T_vstore_qpred_ai_128B<1, 1>,
268                                 V6_vS32b_nt_nqpred_ai_128B_enc;
269
270
271//===----------------------------------------------------------------------===//
272// Vector stores with base + immediate offset - conditional new
273//===----------------------------------------------------------------------===//
274let addrMode = BaseImmOffset, isPredicated = 1, isNewValue = 1, opNewValue = 3,
275    isNVStore = 1, Type = TypeCVI_VM_NEW_ST, Itinerary = CVI_VM_NEW_ST in
276class T_vstore_new_pred_ai <string baseOp, Operand ImmOp, RegisterClass RC,
277                            bit isPredNot, bit isNT>
278  : V6_STInst <(outs),
279               (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$src3, RC:$src4),
280    "if("#!if(isPredNot, "!", "")#"$src1) vmem($src2+#$src3)"
281         #!if(isNT, ":nt", "")#" = $src4.new">, NewValueRel {
282  let isPredicatedFalse = isPredNot;
283  let BaseOpcode = baseOp;
284}
285
286let accessSize = Vector64Access in
287class T_vstore_new_pred_ai_64B <string baseOp, bit isPredNot = 0, bit isNT = 0>
288  : T_vstore_new_pred_ai <baseOp, s4_6Imm, VectorRegs, isPredNot, isNT>;
289
290let isCodeGenOnly = 1, accessSize = Vector128Access in
291class T_vstore_new_pred_ai_128B <string baseOp, bit isPredNot = 0, bit isNT = 0>
292  : T_vstore_new_pred_ai <baseOp#"128B", s4_7Imm, VectorRegs128B,
293                          isPredNot, isNT>;
294
295
296def V6_vS32b_new_pred_ai     : T_vstore_new_pred_ai_64B <"vS32b_ai">,
297                               V6_vS32b_new_pred_ai_enc;
298def V6_vS32b_new_npred_ai    : T_vstore_new_pred_ai_64B <"vS32b_ai", 1>,
299                               V6_vS32b_new_npred_ai_enc;
300// 128B
301def V6_vS32b_new_pred_ai_128B     : T_vstore_new_pred_ai_128B <"vS32b_ai">,
302                                    V6_vS32b_new_pred_ai_128B_enc;
303def V6_vS32b_new_npred_ai_128B    : T_vstore_new_pred_ai_128B <"vS32b_ai", 1>,
304                                    V6_vS32b_new_npred_ai_128B_enc;
305let isNonTemporal = 1 in {
306  def V6_vS32b_nt_new_pred_ai  : T_vstore_new_pred_ai_64B <"vS32b_ai", 0, 1>,
307                                 V6_vS32b_nt_new_pred_ai_enc;
308  def V6_vS32b_nt_new_npred_ai : T_vstore_new_pred_ai_64B <"vS32b_ai", 1, 1>,
309                                 V6_vS32b_nt_new_npred_ai_enc;
310  // 128B
311  def V6_vS32b_nt_new_pred_ai_128B  : T_vstore_new_pred_ai_128B
312                                      <"vS32b_ai", 0, 1>,
313                                      V6_vS32b_nt_new_pred_ai_128B_enc;
314  def V6_vS32b_nt_new_npred_ai_128B : T_vstore_new_pred_ai_128B
315                                      <"vS32b_ai", 1, 1>,
316                                      V6_vS32b_nt_new_npred_ai_128B_enc;
317}
318
319//===----------------------------------------------------------------------===//
320// Post increment vector loads with immediate offset.
321//===----------------------------------------------------------------------===//
322let addrMode = PostInc, hasNewValue = 1 in
323class T_vload_pi<string asmStr, Operand ImmOp, RegisterClass RC>
324  : V6_LDInst <(outs RC:$dst, IntRegs:$_dst_),
325               (ins IntRegs:$src1, ImmOp:$src2), asmStr, [],
326    "$src1 = $_dst_">;
327
328let accessSize = Vector64Access in
329class T_vload_pi_64B <string asmStr>
330  : T_vload_pi <asmStr, s3_6Imm, VectorRegs>;
331
332let isCodeGenOnly = 1, accessSize = Vector128Access in
333class T_vload_pi_128B <string asmStr>
334  : T_vload_pi <asmStr, s3_7Imm, VectorRegs128B>;
335
336let isCVLoadable = 1 in {
337  def V6_vL32b_pi    : T_vload_pi_64B <"$dst = vmem($src1++#$src2)">,
338                       V6_vL32b_pi_enc;
339  def V6_vL32b_nt_pi : T_vload_pi_64B <"$dst = vmem($src1++#$src2):nt">,
340                       V6_vL32b_nt_pi_enc;
341  // 128B
342  def V6_vL32b_pi_128B    : T_vload_pi_128B <"$dst = vmem($src1++#$src2)">,
343                            V6_vL32b_pi_128B_enc;
344  def V6_vL32b_nt_pi_128B : T_vload_pi_128B <"$dst = vmem($src1++#$src2):nt">,
345                            V6_vL32b_nt_pi_128B_enc;
346}
347
348let Itinerary = CVI_VM_VP_LDU, Type = TypeCVI_VM_VP_LDU in {
349  def V6_vL32Ub_pi : T_vload_pi_64B <"$dst = vmemu($src1++#$src2)">,
350                     V6_vL32Ub_pi_enc;
351  // 128B
352  def V6_vL32Ub_pi_128B : T_vload_pi_128B <"$dst = vmemu($src1++#$src2)">,
353                          V6_vL32Ub_pi_128B_enc;
354}
355
356let isCVLoad = 1, Itinerary = CVI_VM_LD, Type = TypeCVI_VM_LD in {
357  def V6_vL32b_cur_pi    : T_vload_pi_64B <"$dst.cur = vmem($src1++#$src2)">,
358                           V6_vL32b_cur_pi_enc;
359  def V6_vL32b_nt_cur_pi : T_vload_pi_64B <"$dst.cur = vmem($src1++#$src2):nt">,
360                           V6_vL32b_nt_cur_pi_enc;
361  // 128B
362  def V6_vL32b_cur_pi_128B    : T_vload_pi_128B
363                                <"$dst.cur = vmem($src1++#$src2)">,
364                                V6_vL32b_cur_pi_128B_enc;
365  def V6_vL32b_nt_cur_pi_128B : T_vload_pi_128B
366                                <"$dst.cur = vmem($src1++#$src2):nt">,
367                                V6_vL32b_nt_cur_pi_128B_enc;
368}
369
370let Itinerary = CVI_VM_TMP_LD, Type = TypeCVI_VM_TMP_LD in {
371  def V6_vL32b_tmp_pi    : T_vload_pi_64B <"$dst.tmp = vmem($src1++#$src2)">,
372                           V6_vL32b_tmp_pi_enc;
373  def V6_vL32b_nt_tmp_pi : T_vload_pi_64B <"$dst.tmp = vmem($src1++#$src2):nt">,
374                           V6_vL32b_nt_tmp_pi_enc;
375  //128B
376  def V6_vL32b_tmp_pi_128B    : T_vload_pi_128B
377                                <"$dst.tmp = vmem($src1++#$src2)">,
378                                V6_vL32b_tmp_pi_128B_enc;
379  def V6_vL32b_nt_tmp_pi_128B : T_vload_pi_128B
380                                <"$dst.tmp = vmem($src1++#$src2):nt">,
381                                V6_vL32b_nt_tmp_pi_128B_enc;
382}
383
384//===----------------------------------------------------------------------===//
385// Post increment vector stores with immediate offset.
386//===----------------------------------------------------------------------===//
387let addrMode = PostInc in
388class T_vstore_pi <string mnemonic, string baseOp, Operand ImmOp,
389                   RegisterClass RC, bit isNT>
390  : V6_STInst <(outs IntRegs:$_dst_),
391               (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
392    mnemonic#"($src1++#$src2)"#!if(isNT, ":nt", "")#" = $src3", [],
393    "$src1 = $_dst_">, NewValueRel;
394
395let accessSize = Vector64Access in
396class T_vstore_pi_64B <string mnemonic, string baseOp, bit isNT = 0>
397  : T_vstore_pi <mnemonic, baseOp, s3_6Imm, VectorRegs, isNT>;
398
399let isCodeGenOnly = 1, accessSize = Vector128Access in
400class T_vstore_pi_128B <string mnemonic, string baseOp, bit isNT = 0>
401  : T_vstore_pi <mnemonic, baseOp, s3_7Imm, VectorRegs128B, isNT>;
402
403let isNVStorable = 1 in {
404  def V6_vS32b_pi      : T_vstore_pi_64B <"vmem", "vS32b_pi">, V6_vS32b_pi_enc;
405  def V6_vS32b_pi_128B : T_vstore_pi_128B <"vmem", "vS32b_pi">,
406                         V6_vS32b_pi_128B_enc;
407}
408
409let isNVStorable = 1 , isNonTemporal = 1  in {
410  def V6_vS32b_nt_pi      : T_vstore_pi_64B <"vmem", "vS32b_pi", 1>,
411                            V6_vS32b_nt_pi_enc;
412  def V6_vS32b_nt_pi_128B : T_vstore_pi_128B <"vmem", "vS32b_pi", 1>,
413                            V6_vS32b_nt_pi_128B_enc;
414}
415
416
417let Itinerary = CVI_VM_STU, Type = TypeCVI_VM_STU in {
418  def V6_vS32Ub_pi      : T_vstore_pi_64B <"vmemu", "vS32Ub_pi">,
419                          V6_vS32Ub_pi_enc;
420  def V6_vS32Ub_pi_128B : T_vstore_pi_128B <"vmemu", "vS32Ub_pi">,
421                          V6_vS32Ub_pi_128B_enc;
422}
423
424//===----------------------------------------------------------------------===//
425// Post increment unconditional .new vector stores with immediate offset.
426//===----------------------------------------------------------------------===//
427let addrMode = PostInc, isNVStore = 1 in
428let Itinerary = CVI_VM_NEW_ST, Type = TypeCVI_VM_NEW_ST, isNewValue = 1,
429    opNewValue = 3, isNVStore = 1 in
430class T_vstore_new_pi <string baseOp, Operand ImmOp, RegisterClass RC, bit isNT>
431  : V6_STInst <(outs IntRegs:$_dst_),
432               (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
433    "vmem($src1++#$src2)"#!if(isNT, ":nt", "")#" = $src3.new", [],
434    "$src1 = $_dst_">, NewValueRel {
435  let BaseOpcode = baseOp;
436}
437
438let accessSize = Vector64Access in
439class T_vstore_new_pi_64B <string baseOp, bit isNT = 0>
440  : T_vstore_new_pi <baseOp, s3_6Imm, VectorRegs, isNT>;
441
442let isCodeGenOnly = 1, accessSize = Vector128Access in
443class T_vstore_new_pi_128B <string baseOp, bit isNT = 0>
444  : T_vstore_new_pi <baseOp#"128B", s3_7Imm, VectorRegs128B, isNT>;
445
446
447def V6_vS32b_new_pi      : T_vstore_new_pi_64B <"vS32b_pi">,
448                           V6_vS32b_new_pi_enc;
449def V6_vS32b_new_pi_128B : T_vstore_new_pi_128B <"vS32b_pi">,
450                           V6_vS32b_new_pi_128B_enc;
451
452let isNonTemporal = 1 in {
453  def V6_vS32b_nt_new_pi      : T_vstore_new_pi_64B <"vS32b_pi", 1>,
454                                V6_vS32b_nt_new_pi_enc;
455  def V6_vS32b_nt_new_pi_128B : T_vstore_new_pi_128B <"vS32b_pi", 1>,
456                                V6_vS32b_nt_new_pi_128B_enc;
457}
458
459//===----------------------------------------------------------------------===//
460// Post increment conditional vector stores with immediate offset
461//===----------------------------------------------------------------------===//
462let isPredicated = 1, addrMode = PostInc in
463class T_vstore_pred_pi <string mnemonic, string baseOp, Operand ImmOp,
464                        RegisterClass RC, bit isPredNot, bit isNT>
465  : V6_STInst<(outs IntRegs:$_dst_),
466             (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$src3, RC:$src4),
467    "if ("#!if(isPredNot, "!", "")#"$src1) "#mnemonic#"($src2++#$src3)"
468          #!if(isNT, ":nt", "")#" = $src4", [],
469    "$src2 = $_dst_">, NewValueRel {
470  let isPredicatedFalse = isPredNot;
471  let BaseOpcode = baseOp;
472}
473
474let accessSize = Vector64Access in
475class T_vstore_pred_pi_64B <string mnemonic, string baseOp,
476                            bit isPredNot = 0, bit isNT = 0>
477  : T_vstore_pred_pi <mnemonic, baseOp, s3_6Imm, VectorRegs, isPredNot, isNT>;
478
479let isCodeGenOnly = 1, accessSize = Vector128Access in
480class T_vstore_pred_pi_128B <string mnemonic, string baseOp,
481                             bit isPredNot = 0, bit isNT = 0>
482  : T_vstore_pred_pi <mnemonic, baseOp#"128B", s3_7Imm, VectorRegs128B,
483                      isPredNot, isNT>;
484
485let isNVStorable = 1 in {
486  def V6_vS32b_pred_pi     : T_vstore_pred_pi_64B <"vmem", "vS32b_pi">,
487                             V6_vS32b_pred_pi_enc;
488  def V6_vS32b_npred_pi    : T_vstore_pred_pi_64B <"vmem", "vS32b_pi", 1>,
489                             V6_vS32b_npred_pi_enc;
490  // 128B
491  def V6_vS32b_pred_pi_128B  : T_vstore_pred_pi_128B <"vmem", "vS32b_pi">,
492                               V6_vS32b_pred_pi_128B_enc;
493  def V6_vS32b_npred_pi_128B : T_vstore_pred_pi_128B <"vmem", "vS32b_pi", 1>,
494                               V6_vS32b_npred_pi_128B_enc;
495}
496let isNVStorable = 1, isNonTemporal = 1 in {
497  def V6_vS32b_nt_pred_pi  : T_vstore_pred_pi_64B <"vmem", "vS32b_pi", 0, 1>,
498                             V6_vS32b_nt_pred_pi_enc;
499  def V6_vS32b_nt_npred_pi : T_vstore_pred_pi_64B <"vmem", "vS32b_pi", 1, 1>,
500                             V6_vS32b_nt_npred_pi_enc;
501  // 128B
502  def V6_vS32b_nt_pred_pi_128B  : T_vstore_pred_pi_128B
503                                  <"vmem", "vS32b_pi", 0, 1>,
504                                  V6_vS32b_nt_pred_pi_128B_enc;
505  def V6_vS32b_nt_npred_pi_128B : T_vstore_pred_pi_128B
506                                  <"vmem", "vS32b_pi", 1, 1>,
507                                  V6_vS32b_nt_npred_pi_128B_enc;
508}
509
510let Itinerary = CVI_VM_STU, Type = TypeCVI_VM_STU in {
511  def V6_vS32Ub_pred_pi  : T_vstore_pred_pi_64B <"vmemu", "vS32Ub_pi">,
512                           V6_vS32Ub_pred_pi_enc;
513  def V6_vS32Ub_npred_pi : T_vstore_pred_pi_64B <"vmemu", "vS32Ub_pi", 1>,
514                           V6_vS32Ub_npred_pi_enc;
515  // 128B
516  def V6_vS32Ub_pred_pi_128B  : T_vstore_pred_pi_128B <"vmemu", "vS32Ub_pi">,
517                                V6_vS32Ub_pred_pi_128B_enc;
518  def V6_vS32Ub_npred_pi_128B : T_vstore_pred_pi_128B <"vmemu", "vS32Ub_pi", 1>,
519                                V6_vS32Ub_npred_pi_128B_enc;
520}
521
522//===----------------------------------------------------------------------===//
523// Post increment vector stores with immediate offset - byte-enabled aligned
524//===----------------------------------------------------------------------===//
525let addrMode = PostInc in
526class T_vstore_qpred_pi <Operand ImmOp, RegisterClass RC, bit isPredNot = 0,
527                         bit isNT = 0>
528  : V6_STInst <(outs IntRegs:$_dst_),
529               (ins VecPredRegs:$src1, IntRegs:$src2, ImmOp:$src3, RC:$src4),
530    "if ("#!if(isPredNot, "!", "")#"$src1) vmem($src2++#$src3)"
531          #!if(isNT, ":nt", "")#" = $src4", [],
532    "$src2 = $_dst_">;
533
534let accessSize = Vector64Access in
535class T_vstore_qpred_pi_64B <bit isPredNot = 0, bit isNT = 0>
536  : T_vstore_qpred_pi <s3_6Imm, VectorRegs, isPredNot, isNT>;
537
538let isCodeGenOnly = 1, accessSize = Vector128Access in
539class T_vstore_qpred_pi_128B <bit isPredNot = 0, bit isNT = 0>
540  : T_vstore_qpred_pi <s3_7Imm, VectorRegs128B, isPredNot, isNT>;
541
542def V6_vS32b_qpred_pi  : T_vstore_qpred_pi_64B, V6_vS32b_qpred_pi_enc;
543def V6_vS32b_nqpred_pi : T_vstore_qpred_pi_64B <1>, V6_vS32b_nqpred_pi_enc;
544// 128B
545def V6_vS32b_qpred_pi_128B  : T_vstore_qpred_pi_128B,
546                              V6_vS32b_qpred_pi_128B_enc;
547def V6_vS32b_nqpred_pi_128B : T_vstore_qpred_pi_128B<1>,
548                              V6_vS32b_nqpred_pi_128B_enc;
549
550let isNonTemporal = 1 in {
551  def V6_vS32b_nt_qpred_pi  : T_vstore_qpred_pi_64B <0, 1>,
552                              V6_vS32b_nt_qpred_pi_enc;
553  def V6_vS32b_nt_nqpred_pi : T_vstore_qpred_pi_64B <1, 1>,
554                              V6_vS32b_nt_nqpred_pi_enc;
555  // 128B
556  def V6_vS32b_nt_qpred_pi_128B  : T_vstore_qpred_pi_128B<0, 1>,
557                                   V6_vS32b_nt_qpred_pi_128B_enc;
558  def V6_vS32b_nt_nqpred_pi_128B : T_vstore_qpred_pi_128B<1, 1>,
559                                   V6_vS32b_nt_nqpred_pi_128B_enc;
560}
561
562//===----------------------------------------------------------------------===//
563// Post increment conditional .new vector stores with immediate offset
564//===----------------------------------------------------------------------===//
565let Itinerary = CVI_VM_NEW_ST, Type = TypeCVI_VM_NEW_ST, isPredicated = 1,
566    isNewValue = 1, opNewValue = 4, addrMode = PostInc, isNVStore = 1 in
567class T_vstore_new_pred_pi <string baseOp, Operand ImmOp, RegisterClass RC,
568                            bit isPredNot, bit isNT>
569  : V6_STInst <(outs IntRegs:$_dst_),
570               (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$src3, RC:$src4),
571    "if("#!if(isPredNot, "!", "")#"$src1) vmem($src2++#$src3)"
572         #!if(isNT, ":nt", "")#" = $src4.new", [],
573    "$src2 = $_dst_"> , NewValueRel {
574  let isPredicatedFalse = isPredNot;
575  let BaseOpcode = baseOp;
576}
577
578let accessSize = Vector64Access in
579class T_vstore_new_pred_pi_64B <string baseOp, bit isPredNot = 0, bit isNT = 0>
580  : T_vstore_new_pred_pi <baseOp, s3_6Imm, VectorRegs, isPredNot, isNT>;
581
582let isCodeGenOnly = 1, accessSize = Vector128Access in
583class T_vstore_new_pred_pi_128B <string baseOp, bit isPredNot = 0, bit isNT = 0>
584  : T_vstore_new_pred_pi <baseOp#"128B", s3_7Imm, VectorRegs128B,
585                          isPredNot, isNT>;
586
587def V6_vS32b_new_pred_pi     : T_vstore_new_pred_pi_64B <"vS32b_pi">,
588                               V6_vS32b_new_pred_pi_enc;
589def V6_vS32b_new_npred_pi    : T_vstore_new_pred_pi_64B <"vS32b_pi", 1>,
590                               V6_vS32b_new_npred_pi_enc;
591// 128B
592def V6_vS32b_new_pred_pi_128B    : T_vstore_new_pred_pi_128B <"vS32b_pi">,
593                                   V6_vS32b_new_pred_pi_128B_enc;
594def V6_vS32b_new_npred_pi_128B   : T_vstore_new_pred_pi_128B <"vS32b_pi", 1>,
595                                   V6_vS32b_new_npred_pi_128B_enc;
596let isNonTemporal = 1 in {
597  def V6_vS32b_nt_new_pred_pi  : T_vstore_new_pred_pi_64B <"vS32b_pi", 0, 1>,
598                                 V6_vS32b_nt_new_pred_pi_enc;
599  def V6_vS32b_nt_new_npred_pi : T_vstore_new_pred_pi_64B <"vS32b_pi", 1, 1>,
600                                 V6_vS32b_nt_new_npred_pi_enc;
601  // 128B
602  def V6_vS32b_nt_new_pred_pi_128B : T_vstore_new_pred_pi_128B
603                                     <"vS32b_pi", 0, 1>,
604                                     V6_vS32b_nt_new_pred_pi_128B_enc;
605  def V6_vS32b_nt_new_npred_pi_128B : T_vstore_new_pred_pi_128B
606                                      <"vS32b_pi", 1, 1>,
607                                      V6_vS32b_nt_new_npred_pi_128B_enc;
608}
609
610//===----------------------------------------------------------------------===//
611// Post increment vector loads with register offset
612//===----------------------------------------------------------------------===//
613let hasNewValue = 1 in
614class T_vload_ppu<string asmStr>
615  : V6_LDInst <(outs VectorRegs:$dst, IntRegs:$_dst_),
616               (ins IntRegs:$src1, ModRegs:$src2), asmStr, [],
617    "$src1 = $_dst_">, NewValueRel;
618
619let isCVLoadable = 1 in {
620  def V6_vL32b_ppu    : T_vload_ppu <"$dst = vmem($src1++$src2)">,
621                        V6_vL32b_ppu_enc;
622  def V6_vL32b_nt_ppu : T_vload_ppu <"$dst = vmem($src1++$src2):nt">,
623                        V6_vL32b_nt_ppu_enc;
624}
625
626let Itinerary = CVI_VM_VP_LDU, Type = TypeCVI_VM_VP_LDU in
627def V6_vL32Ub_ppu : T_vload_ppu <"$dst = vmemu($src1++$src2)">,
628                     V6_vL32Ub_ppu_enc;
629
630let isCVLoad = 1, Itinerary = CVI_VM_CUR_LD, Type = TypeCVI_VM_CUR_LD in {
631  def V6_vL32b_cur_ppu    : T_vload_ppu <"$dst.cur = vmem($src1++$src2)">,
632                             V6_vL32b_cur_ppu_enc;
633  def V6_vL32b_nt_cur_ppu : T_vload_ppu <"$dst.cur = vmem($src1++$src2):nt">,
634                             V6_vL32b_nt_cur_ppu_enc;
635}
636
637let Itinerary = CVI_VM_TMP_LD, Type = TypeCVI_VM_TMP_LD in {
638  def V6_vL32b_tmp_ppu    : T_vload_ppu <"$dst.tmp = vmem($src1++$src2)">,
639                             V6_vL32b_tmp_ppu_enc;
640  def V6_vL32b_nt_tmp_ppu : T_vload_ppu <"$dst.tmp = vmem($src1++$src2):nt">,
641                             V6_vL32b_nt_tmp_ppu_enc;
642}
643
644//===----------------------------------------------------------------------===//
645// Post increment vector stores with register offset
646//===----------------------------------------------------------------------===//
647class T_vstore_ppu <string mnemonic, bit isNT = 0>
648  : V6_STInst <(outs IntRegs:$_dst_),
649               (ins IntRegs:$src1, ModRegs:$src2, VectorRegs:$src3),
650    mnemonic#"($src1++$src2)"#!if(isNT, ":nt", "")#" = $src3", [],
651    "$src1 = $_dst_">, NewValueRel;
652
653let isNVStorable = 1, BaseOpcode = "vS32b_ppu" in {
654  def V6_vS32b_ppu    : T_vstore_ppu <"vmem">,
655                        V6_vS32b_ppu_enc;
656  let isNonTemporal = 1, BaseOpcode = "vS32b_ppu" in
657  def V6_vS32b_nt_ppu : T_vstore_ppu <"vmem", 1>,
658                        V6_vS32b_nt_ppu_enc;
659}
660
661let BaseOpcode = "vS32Ub_ppu", Itinerary = CVI_VM_STU, Type = TypeCVI_VM_STU in
662def V6_vS32Ub_ppu   : T_vstore_ppu <"vmemu">, V6_vS32Ub_ppu_enc;
663
664//===----------------------------------------------------------------------===//
665// Post increment .new vector stores with register offset
666//===----------------------------------------------------------------------===//
667let Itinerary = CVI_VM_NEW_ST, Type = TypeCVI_VM_NEW_ST, isNewValue = 1,
668    opNewValue = 3, isNVStore = 1 in
669class T_vstore_new_ppu <bit isNT = 0>
670  : V6_STInst <(outs IntRegs:$_dst_),
671               (ins IntRegs:$src1, ModRegs:$src2, VectorRegs:$src3),
672    "vmem($src1++$src2)"#!if(isNT, ":nt", "")#" = $src3.new", [],
673    "$src1 = $_dst_">, NewValueRel;
674
675let BaseOpcode = "vS32b_ppu" in
676def V6_vS32b_new_ppu    : T_vstore_new_ppu, V6_vS32b_new_ppu_enc;
677
678let BaseOpcode = "vS32b_ppu", isNonTemporal = 1 in
679def V6_vS32b_nt_new_ppu : T_vstore_new_ppu<1>, V6_vS32b_nt_new_ppu_enc;
680
681//===----------------------------------------------------------------------===//
682// Post increment conditional .new vector stores with register offset
683//===----------------------------------------------------------------------===//
684let isPredicated = 1 in
685class T_vstore_pred_ppu <string mnemonic, bit isPredNot = 0, bit isNT = 0>
686  : V6_STInst<(outs IntRegs:$_dst_),
687           (ins PredRegs:$src1, IntRegs:$src2, ModRegs:$src3, VectorRegs:$src4),
688    "if ("#!if(isPredNot, "!", "")#"$src1) "#mnemonic#"($src2++$src3)"
689          #!if(isNT, ":nt", "")#" = $src4", [],
690    "$src2 = $_dst_">, NewValueRel {
691  let isPredicatedFalse = isPredNot;
692}
693
694let isNVStorable = 1, BaseOpcode = "vS32b_ppu" in {
695  def V6_vS32b_pred_ppu : T_vstore_pred_ppu<"vmem">, V6_vS32b_pred_ppu_enc;
696  def V6_vS32b_npred_ppu: T_vstore_pred_ppu<"vmem", 1>, V6_vS32b_npred_ppu_enc;
697}
698
699let isNVStorable = 1, BaseOpcode = "vS32b_ppu", isNonTemporal = 1 in {
700  def V6_vS32b_nt_pred_ppu  : T_vstore_pred_ppu <"vmem", 0, 1>,
701                              V6_vS32b_nt_pred_ppu_enc;
702  def V6_vS32b_nt_npred_ppu : T_vstore_pred_ppu <"vmem", 1, 1>,
703                              V6_vS32b_nt_npred_ppu_enc;
704}
705
706let BaseOpcode = "vS32Ub_ppu", Itinerary = CVI_VM_STU,
707    Type = TypeCVI_VM_STU in {
708  def V6_vS32Ub_pred_ppu  : T_vstore_pred_ppu <"vmemu">,
709                            V6_vS32Ub_pred_ppu_enc;
710  def V6_vS32Ub_npred_ppu : T_vstore_pred_ppu <"vmemu", 1>,
711                            V6_vS32Ub_npred_ppu_enc;
712}
713
714//===----------------------------------------------------------------------===//
715// Post increment vector stores with register offset - byte-enabled aligned
716//===----------------------------------------------------------------------===//
717class T_vstore_qpred_ppu <bit isPredNot = 0, bit isNT = 0>
718  : V6_STInst <(outs IntRegs:$_dst_),
719        (ins VecPredRegs:$src1, IntRegs:$src2, ModRegs:$src3, VectorRegs:$src4),
720    "if ("#!if(isPredNot, "!", "")#"$src1) vmem($src2++$src3)"
721          #!if(isNT, ":nt", "")#" = $src4", [],
722    "$src2 = $_dst_">, NewValueRel;
723
724def V6_vS32b_qpred_ppu  : T_vstore_qpred_ppu, V6_vS32b_qpred_ppu_enc;
725def V6_vS32b_nqpred_ppu : T_vstore_qpred_ppu<1>, V6_vS32b_nqpred_ppu_enc;
726def V6_vS32b_nt_qpred_ppu  : T_vstore_qpred_ppu<0, 1>,
727                             V6_vS32b_nt_qpred_ppu_enc;
728def V6_vS32b_nt_nqpred_ppu : T_vstore_qpred_ppu<1, 1>,
729                             V6_vS32b_nt_nqpred_ppu_enc;
730
731//===----------------------------------------------------------------------===//
732// Post increment conditional .new vector stores with register offset
733//===----------------------------------------------------------------------===//
734let Itinerary = CVI_VM_NEW_ST, Type = TypeCVI_VM_NEW_ST, isPredicated = 1,
735    isNewValue = 1, opNewValue = 4, isNVStore = 1 in
736class T_vstore_new_pred_ppu <bit isPredNot = 0, bit isNT = 0>
737  : V6_STInst <(outs IntRegs:$_dst_),
738           (ins PredRegs:$src1, IntRegs:$src2, ModRegs:$src3, VectorRegs:$src4),
739    "if("#!if(isPredNot, "!", "")#"$src1) vmem($src2++$src3)"
740         #!if(isNT, ":nt", "")#" = $src4.new", [],
741    "$src2 = $_dst_">, NewValueRel {
742  let isPredicatedFalse = isPredNot;
743}
744
745let BaseOpcode = "vS32b_ppu" in {
746  def V6_vS32b_new_pred_ppu  : T_vstore_new_pred_ppu,
747                               V6_vS32b_new_pred_ppu_enc;
748  def V6_vS32b_new_npred_ppu : T_vstore_new_pred_ppu<1>,
749                               V6_vS32b_new_npred_ppu_enc;
750}
751
752let BaseOpcode = "vS32b_ppu", isNonTemporal = 1 in {
753def V6_vS32b_nt_new_pred_ppu :  T_vstore_new_pred_ppu<0, 1>,
754                                V6_vS32b_nt_new_pred_ppu_enc;
755def V6_vS32b_nt_new_npred_ppu : T_vstore_new_pred_ppu<1, 1>,
756                                V6_vS32b_nt_new_npred_ppu_enc;
757}
758
759let isPseudo = 1, validSubTargets = HasV60SubT in
760class STrivv_template<string mnemonic, Operand ImmOp, RegisterClass RC>:
761        VSTInst<(outs), (ins IntRegs:$addr, ImmOp:$off, RC:$src),
762                #mnemonic#"($addr+#$off) = $src", []>;
763
764def STrivv_indexed: STrivv_template<"vvmem", s4_6Imm, VecDblRegs>,
765                    Requires<[HasV60T, UseHVXSgl]>;
766def STrivv_indexed_128B: STrivv_template<"vvmem", s4_7Imm, VecDblRegs128B>,
767                         Requires<[HasV60T, UseHVXDbl]>;
768
769multiclass STrivv_pats <ValueType VTSgl, ValueType VTDbl> {
770  def : Pat<(store (VTSgl VecDblRegs:$src1), IntRegs:$addr),
771            (STrivv_indexed IntRegs:$addr, #0, (VTSgl VecDblRegs:$src1))>,
772            Requires<[UseHVXSgl]>;
773
774  def : Pat<(store (VTDbl VecDblRegs128B:$src1), IntRegs:$addr),
775            (STrivv_indexed_128B IntRegs:$addr, #0,
776                                 (VTDbl VecDblRegs128B:$src1))>,
777            Requires<[UseHVXDbl]>;
778}
779
780defm : STrivv_pats <v128i8, v256i8>;
781defm : STrivv_pats <v64i16, v128i16>;
782defm : STrivv_pats <v32i32, v64i32>;
783defm : STrivv_pats <v16i64, v32i64>;
784
785
786multiclass vS32b_ai_pats <ValueType VTSgl, ValueType VTDbl> {
787  // Aligned stores
788  def : Pat<(store (VTSgl VectorRegs:$src1), IntRegs:$addr),
789            (V6_vS32b_ai IntRegs:$addr, #0, (VTSgl VectorRegs:$src1))>,
790            Requires<[UseHVXSgl]>;
791
792  // 128B Aligned stores
793  def : Pat<(store (VTDbl VectorRegs128B:$src1), IntRegs:$addr),
794            (V6_vS32b_ai_128B IntRegs:$addr, #0, (VTDbl VectorRegs128B:$src1))>,
795            Requires<[UseHVXDbl]>;
796
797  // Fold Add R+IFF into vector store.
798  let AddedComplexity = 10 in
799  def : Pat<(store (VTSgl VectorRegs:$src1),
800                   (add IntRegs:$src2, s4_6ImmPred:$offset)),
801            (V6_vS32b_ai IntRegs:$src2, s4_6ImmPred:$offset,
802                         (VTSgl VectorRegs:$src1))>,
803            Requires<[UseHVXSgl]>;
804
805  // Fold Add R+IFF into vector store 128B.
806  let AddedComplexity = 10 in
807  def : Pat<(store (VTDbl VectorRegs128B:$src1),
808                   (add IntRegs:$src2, s4_7ImmPred:$offset)),
809            (V6_vS32b_ai_128B IntRegs:$src2, s4_7ImmPred:$offset,
810                              (VTDbl VectorRegs128B:$src1))>,
811            Requires<[UseHVXDbl]>;
812}
813
814defm : vS32b_ai_pats <v64i8,  v128i8>;
815defm : vS32b_ai_pats <v32i16, v64i16>;
816defm : vS32b_ai_pats <v16i32, v32i32>;
817defm : vS32b_ai_pats <v8i64,  v16i64>;
818
819let isPseudo = 1, validSubTargets = HasV60SubT in
820class LDrivv_template<string mnemonic, Operand ImmOp, RegisterClass RC>
821  : V6_LDInst <(outs RC:$dst), (ins IntRegs:$addr, ImmOp:$off),
822               "$dst="#mnemonic#"($addr+#$off)",
823               []>,
824               Requires<[HasV60T,UseHVXSgl]>;
825
826def LDrivv_indexed: LDrivv_template<"vvmem", s4_6Imm, VecDblRegs>;
827def LDrivv_indexed_128B: LDrivv_template<"vvmem", s4_7Imm, VecDblRegs128B>;
828
829multiclass LDrivv_pats <ValueType VTSgl, ValueType VTDbl> {
830  def : Pat < (VTSgl (load IntRegs:$addr)),
831              (LDrivv_indexed IntRegs:$addr, #0) >,
832              Requires<[UseHVXSgl]>;
833
834  def : Pat < (VTDbl (load IntRegs:$addr)),
835              (LDrivv_indexed_128B IntRegs:$addr, #0) >,
836              Requires<[UseHVXDbl]>;
837}
838
839defm : LDrivv_pats <v128i8, v256i8>;
840defm : LDrivv_pats <v64i16, v128i16>;
841defm : LDrivv_pats <v32i32, v64i32>;
842defm : LDrivv_pats <v16i64, v32i64>;
843
844multiclass vL32b_ai_pats <ValueType VTSgl, ValueType VTDbl> {
845  // Aligned loads
846  def : Pat < (VTSgl (load IntRegs:$addr)),
847              (V6_vL32b_ai IntRegs:$addr, #0) >,
848              Requires<[UseHVXSgl]>;
849
850  // 128B Load
851  def : Pat < (VTDbl (load IntRegs:$addr)),
852              (V6_vL32b_ai_128B IntRegs:$addr, #0) >,
853              Requires<[UseHVXDbl]>;
854
855  // Fold Add R+IFF into vector load.
856  let AddedComplexity = 10 in
857  def : Pat<(VTDbl (load (add IntRegs:$src2, s4_7ImmPred:$offset))),
858            (V6_vL32b_ai_128B IntRegs:$src2, s4_7ImmPred:$offset)>,
859             Requires<[UseHVXDbl]>;
860
861  let AddedComplexity = 10 in
862  def : Pat<(VTSgl (load (add IntRegs:$src2, s4_6ImmPred:$offset))),
863            (V6_vL32b_ai IntRegs:$src2, s4_6ImmPred:$offset)>,
864            Requires<[UseHVXSgl]>;
865}
866
867defm : vL32b_ai_pats <v64i8,  v128i8>;
868defm : vL32b_ai_pats <v32i16, v64i16>;
869defm : vL32b_ai_pats <v16i32, v32i32>;
870defm : vL32b_ai_pats <v8i64,  v16i64>;
871
872// Store vector predicate pseudo.
873let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 13,
874    isCodeGenOnly = 1, isPseudo = 1, mayStore = 1, hasSideEffects = 0 in {
875def STriq_pred_V6 : STInst<(outs),
876            (ins IntRegs:$base, s32Imm:$offset, VecPredRegs:$src1),
877            ".error \"should not emit\" ",
878            []>,
879            Requires<[HasV60T,UseHVXSgl]>;
880
881def STriq_pred_vec_V6 : STInst<(outs),
882            (ins IntRegs:$base, s32Imm:$offset, VectorRegs:$src1),
883            ".error \"should not emit\" ",
884            []>,
885            Requires<[HasV60T,UseHVXSgl]>;
886
887def STriq_pred_V6_128B : STInst<(outs),
888            (ins IntRegs:$base, s32Imm:$offset, VecPredRegs128B:$src1),
889            ".error \"should not emit\" ",
890            []>,
891            Requires<[HasV60T,UseHVXDbl]>;
892
893def STriq_pred_vec_V6_128B : STInst<(outs),
894            (ins IntRegs:$base, s32Imm:$offset, VectorRegs128B:$src1),
895            ".error \"should not emit\" ",
896            []>,
897            Requires<[HasV60T,UseHVXDbl]>;
898}
899
900// Load vector predicate pseudo.
901let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13,
902    opExtentAlign = 2, isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in {
903def LDriq_pred_V6 : LDInst<(outs VecPredRegs:$dst),
904            (ins IntRegs:$base, s32Imm:$offset),
905            ".error \"should not emit\" ",
906            []>,
907            Requires<[HasV60T,UseHVXSgl]>;
908def LDriq_pred_vec_V6 : LDInst<(outs VectorRegs:$dst),
909            (ins IntRegs:$base, s32Imm:$offset),
910            ".error \"should not emit\" ",
911            []>,
912            Requires<[HasV60T,UseHVXSgl]>;
913def LDriq_pred_V6_128B : LDInst<(outs VecPredRegs128B:$dst),
914            (ins IntRegs:$base, s32Imm:$offset),
915            ".error \"should not emit\" ",
916            []>,
917            Requires<[HasV60T,UseHVXDbl]>;
918def LDriq_pred_vec_V6_128B : LDInst<(outs VectorRegs128B:$dst),
919            (ins IntRegs:$base, s32Imm:$offset),
920            ".error \"should not emit\" ",
921            []>,
922            Requires<[HasV60T,UseHVXDbl]>;
923}
924
925// Store vector pseudo.
926let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 13,
927    isCodeGenOnly = 1, isPseudo = 1, mayStore = 1, hasSideEffects = 0 in {
928def STriv_pseudo_V6 : STInst<(outs),
929            (ins IntRegs:$base, s32Imm:$offset, VectorRegs:$src1),
930            ".error \"should not emit\" ",
931            []>,
932            Requires<[HasV60T,UseHVXSgl]>;
933def STriv_pseudo_V6_128B : STInst<(outs),
934            (ins IntRegs:$base, s32Imm:$offset, VectorRegs128B:$src1),
935            ".error \"should not emit\" ",
936            []>,
937            Requires<[HasV60T,UseHVXDbl]>;
938}
939
940let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 13,
941    isCodeGenOnly = 1, isPseudo = 1, mayStore = 1, hasSideEffects = 0 in {
942def STrivv_pseudo_V6 : STInst<(outs),
943            (ins IntRegs:$base, s32Imm:$offset, VecDblRegs:$src1),
944            ".error \"should not emit\" ",
945            []>,
946            Requires<[HasV60T,UseHVXSgl]>;
947def STrivv_pseudo_V6_128B : STInst<(outs),
948            (ins IntRegs:$base, s32Imm:$offset, VecDblRegs128B:$src1),
949            ".error \"should not emit\" ",
950            []>,
951            Requires<[HasV60T,UseHVXDbl]>;
952}
953
954// Load vector pseudo.
955let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13,
956    opExtentAlign = 2, isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in {
957def LDriv_pseudo_V6 : LDInst<(outs VectorRegs:$dst),
958            (ins IntRegs:$base, s32Imm:$offset),
959            ".error \"should not emit\" ",
960            []>,
961            Requires<[HasV60T,UseHVXSgl]>;
962def LDriv_pseudo_V6_128B : LDInst<(outs VectorRegs128B:$dst),
963            (ins IntRegs:$base, s32Imm:$offset),
964            ".error \"should not emit\" ",
965            []>,
966            Requires<[HasV60T,UseHVXDbl]>;
967}
968
969let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13,
970    opExtentAlign = 2, isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in {
971def LDrivv_pseudo_V6 : LDInst<(outs VecDblRegs:$dst),
972            (ins IntRegs:$base, s32Imm:$offset),
973            ".error \"should not emit\" ",
974            []>,
975            Requires<[HasV60T,UseHVXSgl]>;
976def LDrivv_pseudo_V6_128B : LDInst<(outs VecDblRegs128B:$dst),
977            (ins IntRegs:$base, s32Imm:$offset),
978            ".error \"should not emit\" ",
979            []>,
980            Requires<[HasV60T,UseHVXDbl]>;
981}
982
983class VSELInst<dag outs, dag ins, string asmstr, list<dag> pattern = [],
984              string cstr = "", InstrItinClass itin = CVI_VA_DV,
985              IType type = TypeCVI_VA_DV>
986  : InstHexagon<outs, ins, asmstr, pattern, cstr, itin, type>;
987
988let isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in {
989def VSelectPseudo_V6 : VSELInst<(outs VectorRegs:$dst),
990            (ins PredRegs:$src1, VectorRegs:$src2, VectorRegs:$src3),
991            ".error \"should not emit\" ",
992            []>,
993            Requires<[HasV60T,UseHVXSgl]>;
994def VSelectDblPseudo_V6 : VSELInst<(outs VecDblRegs:$dst),
995               (ins PredRegs:$src1, VecDblRegs:$src2, VecDblRegs:$src3),
996               ".error \"should not emit\" ",
997               []>,
998               Requires<[HasV60T,UseHVXSgl]>;
999}
1000
1001def : Pat <(v16i32 (selectcc (i32 IntRegs:$lhs), (i32 IntRegs:$rhs),
1002                             (v16i32 VectorRegs:$tval),
1003                             (v16i32 VectorRegs:$fval), SETEQ)),
1004      (v16i32 (VSelectPseudo_V6 (i32 (C2_cmpeq (i32 IntRegs:$lhs),
1005                                (i32 IntRegs:$rhs))),
1006                                (v16i32 VectorRegs:$tval),
1007                                (v16i32 VectorRegs:$fval)))>;
1008
1009
1010let hasNewValue = 1 in
1011class T_vmpy <string asmString, RegisterClass RCout, RegisterClass RCin>
1012  : CVI_VX_DV_Resource1<(outs RCout:$dst), (ins RCin:$src1, IntRegs:$src2),
1013    asmString >;
1014
1015multiclass T_vmpy <string asmString, RegisterClass RCout,
1016                        RegisterClass RCin> {
1017  def NAME : T_vmpy <asmString, RCout, RCin>;
1018  let isCodeGenOnly = 1 in
1019  def NAME#_128B : T_vmpy <asmString, !cast<RegisterClass>(RCout#"128B"),
1020                                      !cast<RegisterClass>(RCin#"128B")>;
1021}
1022
1023multiclass T_vmpy_VV <string asmString>:
1024  T_vmpy <asmString, VectorRegs, VectorRegs>;
1025
1026multiclass T_vmpy_WW <string asmString>:
1027  T_vmpy <asmString, VecDblRegs, VecDblRegs>;
1028
1029multiclass T_vmpy_VW <string asmString>:
1030  T_vmpy <asmString, VectorRegs, VecDblRegs>;
1031
1032multiclass T_vmpy_WV <string asmString>:
1033  T_vmpy <asmString, VecDblRegs, VectorRegs>;
1034
1035defm V6_vtmpyb   :T_vmpy_WW<"$dst.h = vtmpy($src1.b,$src2.b)">, V6_vtmpyb_enc;
1036defm V6_vtmpybus :T_vmpy_WW<"$dst.h = vtmpy($src1.ub,$src2.b)">, V6_vtmpybus_enc;
1037defm V6_vdsaduh  :T_vmpy_WW<"$dst.uw = vdsad($src1.uh,$src2.uh)">, V6_vdsaduh_enc;
1038defm V6_vmpybus  :T_vmpy_WV<"$dst.h = vmpy($src1.ub,$src2.b)">, V6_vmpybus_enc;
1039defm V6_vmpabus  :T_vmpy_WW<"$dst.h = vmpa($src1.ub,$src2.b)">, V6_vmpabus_enc;
1040defm V6_vmpahb   :T_vmpy_WW<"$dst.w = vmpa($src1.h,$src2.b)">, V6_vmpahb_enc;
1041defm V6_vmpyh    :T_vmpy_WV<"$dst.w = vmpy($src1.h,$src2.h)">, V6_vmpyh_enc;
1042defm V6_vmpyuh   :T_vmpy_WV<"$dst.uw = vmpy($src1.uh,$src2.uh)">, V6_vmpyuh_enc;
1043defm V6_vmpyiwh  :T_vmpy_VV<"$dst.w = vmpyi($src1.w,$src2.h)">, V6_vmpyiwh_enc;
1044defm V6_vtmpyhb  :T_vmpy_WW<"$dst.w = vtmpy($src1.h,$src2.b)">, V6_vtmpyhb_enc;
1045defm V6_vmpyub   :T_vmpy_WV<"$dst.uh = vmpy($src1.ub,$src2.ub)">, V6_vmpyub_enc;
1046
1047let Itinerary = CVI_VX_LONG, Type = TypeCVI_VX in
1048defm V6_vmpyihb  :T_vmpy_VV<"$dst.h = vmpyi($src1.h,$src2.b)">, V6_vmpyihb_enc;
1049
1050defm V6_vdmpybus_dv :
1051     T_vmpy_WW <"$dst.h = vdmpy($src1.ub,$src2.b)">, V6_vdmpybus_dv_enc;
1052defm V6_vdmpyhsusat :
1053     T_vmpy_VV <"$dst.w = vdmpy($src1.h,$src2.uh):sat">, V6_vdmpyhsusat_enc;
1054defm V6_vdmpyhsuisat :
1055     T_vmpy_VW <"$dst.w = vdmpy($src1.h,$src2.uh,#1):sat">, V6_vdmpyhsuisat_enc;
1056defm V6_vdmpyhsat :
1057     T_vmpy_VV <"$dst.w = vdmpy($src1.h,$src2.h):sat">, V6_vdmpyhsat_enc;
1058defm V6_vdmpyhisat :
1059     T_vmpy_VW <"$dst.w = vdmpy($src1.h,$src2.h):sat">, V6_vdmpyhisat_enc;
1060defm V6_vdmpyhb_dv :
1061     T_vmpy_WW <"$dst.w = vdmpy($src1.h,$src2.b)">, V6_vdmpyhb_dv_enc;
1062defm V6_vmpyhss :
1063     T_vmpy_VV <"$dst.h = vmpy($src1.h,$src2.h):<<1:sat">, V6_vmpyhss_enc;
1064defm V6_vmpyhsrs :
1065     T_vmpy_VV <"$dst.h = vmpy($src1.h,$src2.h):<<1:rnd:sat">, V6_vmpyhsrs_enc;
1066
1067let Itinerary = CVI_VP, Type = TypeCVI_VP in
1068defm V6_vror : T_vmpy_VV <"$dst = vror($src1,$src2)">, V6_vror_enc;
1069
1070let Itinerary = CVI_VX, Type = TypeCVI_VX in {
1071defm V6_vdmpyhb  : T_vmpy_VV<"$dst.w = vdmpy($src1.h,$src2.b)">, V6_vdmpyhb_enc;
1072defm V6_vrmpybus : T_vmpy_VV<"$dst.w = vrmpy($src1.ub,$src2.b)">, V6_vrmpybus_enc;
1073defm V6_vdmpybus : T_vmpy_VV<"$dst.h = vdmpy($src1.ub,$src2.b)">, V6_vdmpybus_enc;
1074defm V6_vmpyiwb  : T_vmpy_VV<"$dst.w = vmpyi($src1.w,$src2.b)">, V6_vmpyiwb_enc;
1075defm V6_vrmpyub : T_vmpy_VV<"$dst.uw = vrmpy($src1.ub,$src2.ub)">, V6_vrmpyub_enc;
1076}
1077
1078let Itinerary = CVI_VS, Type = TypeCVI_VS in {
1079defm V6_vasrw  : T_vmpy_VV <"$dst.w = vasr($src1.w,$src2)">, V6_vasrw_enc;
1080defm V6_vasrh  : T_vmpy_VV <"$dst.h = vasr($src1.h,$src2)">, V6_vasrh_enc;
1081defm V6_vaslw  : T_vmpy_VV <"$dst.w = vasl($src1.w,$src2)">, V6_vaslw_enc;
1082defm V6_vaslh  : T_vmpy_VV <"$dst.h = vasl($src1.h,$src2)">, V6_vaslh_enc;
1083defm V6_vlsrw  : T_vmpy_VV <"$dst.uw = vlsr($src1.uw,$src2)">, V6_vlsrw_enc;
1084defm V6_vlsrh  : T_vmpy_VV <"$dst.uh = vlsr($src1.uh,$src2)">, V6_vlsrh_enc;
1085}
1086
1087let hasNewValue = 1 in
1088class T_HVX_alu <string asmString, InstrItinClass itin,
1089                 RegisterClass RCout, RegisterClass RCin>
1090  : CVI_VA_Resource1 <(outs RCout:$dst), (ins RCin:$src1, RCin:$src2),
1091    asmString >{
1092  let Itinerary = itin;
1093  let Type = !cast<IType>("Type"#itin);
1094}
1095
1096multiclass T_HVX_alu <string asmString, RegisterClass RCout,
1097           RegisterClass RCin, InstrItinClass itin> {
1098  def NAME : T_HVX_alu <asmString, itin, RCout, RCin>;
1099  let isCodeGenOnly = 1 in
1100  def NAME#_128B : T_HVX_alu <asmString, itin,
1101                              !cast<RegisterClass>(RCout#"128B"),
1102                              !cast<RegisterClass>(RCin#"128B")>;
1103}
1104
1105multiclass T_HVX_alu_VV <string asmString>:
1106  T_HVX_alu <asmString, VectorRegs, VectorRegs, CVI_VA>;
1107
1108multiclass T_HVX_alu_WW <string asmString>:
1109  T_HVX_alu <asmString, VecDblRegs, VecDblRegs, CVI_VA_DV>;
1110
1111multiclass T_HVX_alu_WV <string asmString>:
1112  T_HVX_alu <asmString, VecDblRegs, VectorRegs, CVI_VX_DV>;
1113
1114
1115let Itinerary  =  CVI_VX, Type  =  TypeCVI_VX in {
1116defm V6_vrmpyubv :
1117     T_HVX_alu_VV <"$dst.uw = vrmpy($src1.ub,$src2.ub)">, V6_vrmpyubv_enc;
1118defm V6_vrmpybv :
1119     T_HVX_alu_VV <"$dst.w = vrmpy($src1.b,$src2.b)">, V6_vrmpybv_enc;
1120defm V6_vrmpybusv :
1121     T_HVX_alu_VV <"$dst.w = vrmpy($src1.ub,$src2.b)">, V6_vrmpybusv_enc;
1122defm V6_vabsdiffub :
1123     T_HVX_alu_VV <"$dst.ub = vabsdiff($src1.ub,$src2.ub)">, V6_vabsdiffub_enc;
1124defm V6_vabsdiffh :
1125     T_HVX_alu_VV <"$dst.uh = vabsdiff($src1.h,$src2.h)">, V6_vabsdiffh_enc;
1126defm V6_vabsdiffuh :
1127     T_HVX_alu_VV <"$dst.uh = vabsdiff($src1.uh,$src2.uh)">, V6_vabsdiffuh_enc;
1128defm V6_vabsdiffw :
1129     T_HVX_alu_VV <"$dst.uw = vabsdiff($src1.w,$src2.w)">, V6_vabsdiffw_enc;
1130}
1131
1132let Itinerary = CVI_VX_DV, Type = TypeCVI_VX_DV in {
1133defm V6_vdmpyhvsat :
1134     T_HVX_alu_VV <"$dst.w = vdmpy($src1.h,$src2.h):sat">, V6_vdmpyhvsat_enc;
1135defm V6_vmpyhvsrs :
1136     T_HVX_alu_VV<"$dst.h = vmpy($src1.h,$src2.h):<<1:rnd:sat">, V6_vmpyhvsrs_enc;
1137defm V6_vmpyih :
1138     T_HVX_alu_VV <"$dst.h = vmpyi($src1.h,$src2.h)">, V6_vmpyih_enc;
1139}
1140
1141defm V6_vand :
1142     T_HVX_alu_VV <"$dst = vand($src1,$src2)">, V6_vand_enc;
1143defm V6_vor :
1144     T_HVX_alu_VV <"$dst = vor($src1,$src2)">, V6_vor_enc;
1145defm V6_vxor :
1146     T_HVX_alu_VV <"$dst = vxor($src1,$src2)">, V6_vxor_enc;
1147defm V6_vaddw :
1148     T_HVX_alu_VV <"$dst.w = vadd($src1.w,$src2.w)">, V6_vaddw_enc;
1149defm V6_vaddubsat :
1150     T_HVX_alu_VV <"$dst.ub = vadd($src1.ub,$src2.ub):sat">, V6_vaddubsat_enc;
1151defm V6_vadduhsat :
1152     T_HVX_alu_VV <"$dst.uh = vadd($src1.uh,$src2.uh):sat">, V6_vadduhsat_enc;
1153defm V6_vaddhsat :
1154     T_HVX_alu_VV <"$dst.h = vadd($src1.h,$src2.h):sat">, V6_vaddhsat_enc;
1155defm V6_vaddwsat :
1156     T_HVX_alu_VV <"$dst.w = vadd($src1.w,$src2.w):sat">, V6_vaddwsat_enc;
1157defm V6_vsubb :
1158     T_HVX_alu_VV <"$dst.b = vsub($src1.b,$src2.b)">, V6_vsubb_enc;
1159defm V6_vsubh :
1160     T_HVX_alu_VV <"$dst.h = vsub($src1.h,$src2.h)">, V6_vsubh_enc;
1161defm V6_vsubw :
1162     T_HVX_alu_VV <"$dst.w = vsub($src1.w,$src2.w)">, V6_vsubw_enc;
1163defm V6_vsububsat :
1164     T_HVX_alu_VV <"$dst.ub = vsub($src1.ub,$src2.ub):sat">, V6_vsububsat_enc;
1165defm V6_vsubuhsat :
1166     T_HVX_alu_VV <"$dst.uh = vsub($src1.uh,$src2.uh):sat">, V6_vsubuhsat_enc;
1167defm V6_vsubhsat :
1168     T_HVX_alu_VV <"$dst.h = vsub($src1.h,$src2.h):sat">, V6_vsubhsat_enc;
1169defm V6_vsubwsat :
1170     T_HVX_alu_VV <"$dst.w = vsub($src1.w,$src2.w):sat">, V6_vsubwsat_enc;
1171defm V6_vavgub :
1172     T_HVX_alu_VV <"$dst.ub = vavg($src1.ub,$src2.ub)">, V6_vavgub_enc;
1173defm V6_vavguh :
1174     T_HVX_alu_VV <"$dst.uh = vavg($src1.uh,$src2.uh)">, V6_vavguh_enc;
1175defm V6_vavgh :
1176     T_HVX_alu_VV <"$dst.h = vavg($src1.h,$src2.h)">, V6_vavgh_enc;
1177defm V6_vavgw :
1178     T_HVX_alu_VV <"$dst.w = vavg($src1.w,$src2.w)">, V6_vavgw_enc;
1179defm V6_vnavgub :
1180     T_HVX_alu_VV <"$dst.b = vnavg($src1.ub,$src2.ub)">, V6_vnavgub_enc;
1181defm V6_vnavgh :
1182     T_HVX_alu_VV <"$dst.h = vnavg($src1.h,$src2.h)">, V6_vnavgh_enc;
1183defm V6_vnavgw :
1184     T_HVX_alu_VV <"$dst.w = vnavg($src1.w,$src2.w)">, V6_vnavgw_enc;
1185defm V6_vavgubrnd :
1186     T_HVX_alu_VV <"$dst.ub = vavg($src1.ub,$src2.ub):rnd">, V6_vavgubrnd_enc;
1187defm V6_vavguhrnd :
1188     T_HVX_alu_VV <"$dst.uh = vavg($src1.uh,$src2.uh):rnd">, V6_vavguhrnd_enc;
1189defm V6_vavghrnd :
1190     T_HVX_alu_VV <"$dst.h = vavg($src1.h,$src2.h):rnd">, V6_vavghrnd_enc;
1191defm V6_vavgwrnd :
1192     T_HVX_alu_VV <"$dst.w = vavg($src1.w,$src2.w):rnd">, V6_vavgwrnd_enc;
1193
1194defm V6_vmpybv :
1195     T_HVX_alu_WV <"$dst.h = vmpy($src1.b,$src2.b)">, V6_vmpybv_enc;
1196defm V6_vmpyubv :
1197     T_HVX_alu_WV <"$dst.uh = vmpy($src1.ub,$src2.ub)">, V6_vmpyubv_enc;
1198defm V6_vmpybusv :
1199     T_HVX_alu_WV <"$dst.h = vmpy($src1.ub,$src2.b)">, V6_vmpybusv_enc;
1200defm V6_vmpyhv :
1201     T_HVX_alu_WV <"$dst.w = vmpy($src1.h,$src2.h)">, V6_vmpyhv_enc;
1202defm V6_vmpyuhv :
1203     T_HVX_alu_WV <"$dst.uw = vmpy($src1.uh,$src2.uh)">, V6_vmpyuhv_enc;
1204defm V6_vmpyhus :
1205     T_HVX_alu_WV <"$dst.w = vmpy($src1.h,$src2.uh)">, V6_vmpyhus_enc;
1206defm V6_vaddubh :
1207     T_HVX_alu_WV <"$dst.h = vadd($src1.ub,$src2.ub)">, V6_vaddubh_enc;
1208defm V6_vadduhw :
1209     T_HVX_alu_WV <"$dst.w = vadd($src1.uh,$src2.uh)">, V6_vadduhw_enc;
1210defm V6_vaddhw :
1211     T_HVX_alu_WV <"$dst.w = vadd($src1.h,$src2.h)">, V6_vaddhw_enc;
1212defm V6_vsububh :
1213     T_HVX_alu_WV <"$dst.h = vsub($src1.ub,$src2.ub)">, V6_vsububh_enc;
1214defm V6_vsubuhw :
1215     T_HVX_alu_WV <"$dst.w = vsub($src1.uh,$src2.uh)">, V6_vsubuhw_enc;
1216defm V6_vsubhw :
1217     T_HVX_alu_WV <"$dst.w = vsub($src1.h,$src2.h)">, V6_vsubhw_enc;
1218
1219defm V6_vaddb_dv :
1220     T_HVX_alu_WW <"$dst.b = vadd($src1.b,$src2.b)">, V6_vaddb_dv_enc;
1221defm V6_vaddh_dv :
1222     T_HVX_alu_WW <"$dst.h = vadd($src1.h,$src2.h)">, V6_vaddh_dv_enc;
1223defm V6_vaddw_dv :
1224     T_HVX_alu_WW <"$dst.w = vadd($src1.w,$src2.w)">, V6_vaddw_dv_enc;
1225defm V6_vaddubsat_dv :
1226     T_HVX_alu_WW <"$dst.ub = vadd($src1.ub,$src2.ub):sat">, V6_vaddubsat_dv_enc;
1227defm V6_vadduhsat_dv :
1228     T_HVX_alu_WW <"$dst.uh = vadd($src1.uh,$src2.uh):sat">, V6_vadduhsat_dv_enc;
1229defm V6_vaddhsat_dv :
1230     T_HVX_alu_WW <"$dst.h = vadd($src1.h,$src2.h):sat">, V6_vaddhsat_dv_enc;
1231defm V6_vaddwsat_dv :
1232     T_HVX_alu_WW <"$dst.w = vadd($src1.w,$src2.w):sat">, V6_vaddwsat_dv_enc;
1233defm V6_vsubb_dv :
1234     T_HVX_alu_WW <"$dst.b = vsub($src1.b,$src2.b)">, V6_vsubb_dv_enc;
1235defm V6_vsubh_dv :
1236     T_HVX_alu_WW <"$dst.h = vsub($src1.h,$src2.h)">, V6_vsubh_dv_enc;
1237defm V6_vsubw_dv :
1238     T_HVX_alu_WW <"$dst.w = vsub($src1.w,$src2.w)">, V6_vsubw_dv_enc;
1239defm V6_vsububsat_dv :
1240     T_HVX_alu_WW <"$dst.ub = vsub($src1.ub,$src2.ub):sat">, V6_vsububsat_dv_enc;
1241defm V6_vsubuhsat_dv :
1242     T_HVX_alu_WW <"$dst.uh = vsub($src1.uh,$src2.uh):sat">, V6_vsubuhsat_dv_enc;
1243defm V6_vsubhsat_dv :
1244     T_HVX_alu_WW <"$dst.h = vsub($src1.h,$src2.h):sat">, V6_vsubhsat_dv_enc;
1245defm V6_vsubwsat_dv :
1246     T_HVX_alu_WW <"$dst.w = vsub($src1.w,$src2.w):sat">, V6_vsubwsat_dv_enc;
1247
1248let Itinerary = CVI_VX_DV_LONG, Type = TypeCVI_VX_DV in {
1249defm V6_vmpabusv :
1250     T_HVX_alu_WW <"$dst.h = vmpa($src1.ub,$src2.b)">, V6_vmpabusv_enc;
1251defm V6_vmpabuuv :
1252     T_HVX_alu_WW <"$dst.h = vmpa($src1.ub,$src2.ub)">, V6_vmpabuuv_enc;
1253}
1254
1255let isAccumulator = 1, hasNewValue = 1 in
1256class T_HVX_vmpyacc <string asmString, InstrItinClass itin, RegisterClass RCout,
1257                     RegisterClass RCin1, RegisterClass RCin2>
1258  : CVI_VA_Resource1 <(outs RCout:$dst),
1259                      (ins RCout:$_src_, RCin1:$src1, RCin2:$src2), asmString,
1260                      [], "$dst = $_src_" > {
1261  let Itinerary = itin;
1262  let Type = !cast<IType>("Type"#itin);
1263}
1264
1265multiclass T_HVX_vmpyacc_both <string asmString, RegisterClass RCout,
1266           RegisterClass RCin1, RegisterClass RCin2, InstrItinClass itin > {
1267  def NAME : T_HVX_vmpyacc <asmString, itin, RCout, RCin1, RCin2>;
1268  let isCodeGenOnly = 1 in
1269  def NAME#_128B : T_HVX_vmpyacc <asmString, itin,
1270                   !cast<RegisterClass>(RCout#"128B"),
1271                   !cast<RegisterClass>(RCin1#"128B"),
1272                   !cast<RegisterClass>(RCin2#
1273                   !if(!eq (!cast<string>(RCin2), "IntRegs"), "", "128B"))>;
1274}
1275
1276multiclass T_HVX_vmpyacc_VVR <string asmString>:
1277  T_HVX_vmpyacc_both <asmString, VectorRegs, VectorRegs, IntRegs, CVI_VX>;
1278
1279multiclass T_HVX_vmpyacc_VWR <string asmString>:
1280  T_HVX_vmpyacc_both <asmString, VectorRegs, VecDblRegs, IntRegs, CVI_VX_DV>;
1281
1282multiclass T_HVX_vmpyacc_WVR <string asmString>:
1283  T_HVX_vmpyacc_both <asmString, VecDblRegs, VectorRegs, IntRegs, CVI_VX_DV>;
1284
1285multiclass T_HVX_vmpyacc_WWR <string asmString>:
1286  T_HVX_vmpyacc_both <asmString, VecDblRegs, VecDblRegs, IntRegs, CVI_VX_DV>;
1287
1288multiclass T_HVX_vmpyacc_VVV <string asmString>:
1289  T_HVX_vmpyacc_both <asmString, VectorRegs, VectorRegs, VectorRegs, CVI_VX_DV>;
1290
1291multiclass T_HVX_vmpyacc_WVV <string asmString>:
1292  T_HVX_vmpyacc_both <asmString, VecDblRegs, VectorRegs, VectorRegs, CVI_VX_DV>;
1293
1294
1295defm V6_vtmpyb_acc :
1296     T_HVX_vmpyacc_WWR <"$dst.h += vtmpy($src1.b,$src2.b)">,
1297     V6_vtmpyb_acc_enc;
1298defm V6_vtmpybus_acc :
1299     T_HVX_vmpyacc_WWR <"$dst.h += vtmpy($src1.ub,$src2.b)">,
1300     V6_vtmpybus_acc_enc;
1301defm V6_vtmpyhb_acc :
1302     T_HVX_vmpyacc_WWR <"$dst.w += vtmpy($src1.h,$src2.b)">,
1303     V6_vtmpyhb_acc_enc;
1304defm V6_vdmpyhb_acc :
1305     T_HVX_vmpyacc_VVR <"$dst.w += vdmpy($src1.h,$src2.b)">,
1306     V6_vdmpyhb_acc_enc;
1307defm V6_vrmpyub_acc :
1308     T_HVX_vmpyacc_VVR <"$dst.uw += vrmpy($src1.ub,$src2.ub)">,
1309     V6_vrmpyub_acc_enc;
1310defm V6_vrmpybus_acc :
1311     T_HVX_vmpyacc_VVR <"$dst.w += vrmpy($src1.ub,$src2.b)">,
1312     V6_vrmpybus_acc_enc;
1313defm V6_vdmpybus_acc :
1314     T_HVX_vmpyacc_VVR <"$dst.h += vdmpy($src1.ub,$src2.b)">,
1315     V6_vdmpybus_acc_enc;
1316defm V6_vdmpybus_dv_acc :
1317     T_HVX_vmpyacc_WWR <"$dst.h += vdmpy($src1.ub,$src2.b)">,
1318     V6_vdmpybus_dv_acc_enc;
1319defm V6_vdmpyhsuisat_acc :
1320     T_HVX_vmpyacc_VWR <"$dst.w += vdmpy($src1.h,$src2.uh,#1):sat">,
1321     V6_vdmpyhsuisat_acc_enc;
1322defm V6_vdmpyhisat_acc :
1323     T_HVX_vmpyacc_VWR <"$dst.w += vdmpy($src1.h,$src2.h):sat">,
1324     V6_vdmpyhisat_acc_enc;
1325defm V6_vdmpyhb_dv_acc :
1326     T_HVX_vmpyacc_WWR <"$dst.w += vdmpy($src1.h,$src2.b)">,
1327     V6_vdmpyhb_dv_acc_enc;
1328defm V6_vmpybus_acc :
1329     T_HVX_vmpyacc_WVR <"$dst.h += vmpy($src1.ub,$src2.b)">,
1330     V6_vmpybus_acc_enc;
1331defm V6_vmpabus_acc :
1332     T_HVX_vmpyacc_WWR <"$dst.h += vmpa($src1.ub,$src2.b)">,
1333     V6_vmpabus_acc_enc;
1334defm V6_vmpahb_acc :
1335     T_HVX_vmpyacc_WWR <"$dst.w += vmpa($src1.h,$src2.b)">,
1336     V6_vmpahb_acc_enc;
1337defm V6_vmpyhsat_acc :
1338     T_HVX_vmpyacc_WVR <"$dst.w += vmpy($src1.h,$src2.h):sat">,
1339     V6_vmpyhsat_acc_enc;
1340defm V6_vmpyuh_acc :
1341     T_HVX_vmpyacc_WVR <"$dst.uw += vmpy($src1.uh,$src2.uh)">,
1342     V6_vmpyuh_acc_enc;
1343defm V6_vmpyiwb_acc :
1344     T_HVX_vmpyacc_VVR <"$dst.w += vmpyi($src1.w,$src2.b)">,
1345     V6_vmpyiwb_acc_enc;
1346defm V6_vdsaduh_acc :
1347     T_HVX_vmpyacc_WWR <"$dst.uw += vdsad($src1.uh,$src2.uh)">,
1348     V6_vdsaduh_acc_enc;
1349defm V6_vmpyihb_acc :
1350     T_HVX_vmpyacc_VVR <"$dst.h += vmpyi($src1.h,$src2.b)">,
1351     V6_vmpyihb_acc_enc;
1352defm V6_vmpyub_acc :
1353     T_HVX_vmpyacc_WVR <"$dst.uh += vmpy($src1.ub,$src2.ub)">,
1354     V6_vmpyub_acc_enc;
1355
1356let Itinerary = CVI_VX_DV, Type = TypeCVI_VX_DV in {
1357defm V6_vdmpyhsusat_acc :
1358     T_HVX_vmpyacc_VVR <"$dst.w += vdmpy($src1.h,$src2.uh):sat">,
1359     V6_vdmpyhsusat_acc_enc;
1360defm V6_vdmpyhsat_acc :
1361     T_HVX_vmpyacc_VVR <"$dst.w += vdmpy($src1.h,$src2.h):sat">,
1362     V6_vdmpyhsat_acc_enc;
1363defm V6_vmpyiwh_acc : T_HVX_vmpyacc_VVR
1364     <"$dst.w += vmpyi($src1.w,$src2.h)">, V6_vmpyiwh_acc_enc;
1365}
1366
1367let Itinerary = CVI_VS, Type = TypeCVI_VS in {
1368defm V6_vaslw_acc :
1369     T_HVX_vmpyacc_VVR <"$dst.w += vasl($src1.w,$src2)">, V6_vaslw_acc_enc;
1370defm V6_vasrw_acc :
1371     T_HVX_vmpyacc_VVR <"$dst.w += vasr($src1.w,$src2)">, V6_vasrw_acc_enc;
1372}
1373
1374defm V6_vdmpyhvsat_acc :
1375     T_HVX_vmpyacc_VVV <"$dst.w += vdmpy($src1.h,$src2.h):sat">,
1376     V6_vdmpyhvsat_acc_enc;
1377defm V6_vmpybusv_acc :
1378     T_HVX_vmpyacc_WVV <"$dst.h += vmpy($src1.ub,$src2.b)">,
1379     V6_vmpybusv_acc_enc;
1380defm V6_vmpybv_acc :
1381     T_HVX_vmpyacc_WVV <"$dst.h += vmpy($src1.b,$src2.b)">, V6_vmpybv_acc_enc;
1382defm V6_vmpyhus_acc :
1383     T_HVX_vmpyacc_WVV <"$dst.w += vmpy($src1.h,$src2.uh)">, V6_vmpyhus_acc_enc;
1384defm V6_vmpyhv_acc :
1385     T_HVX_vmpyacc_WVV <"$dst.w += vmpy($src1.h,$src2.h)">, V6_vmpyhv_acc_enc;
1386defm V6_vmpyiewh_acc :
1387     T_HVX_vmpyacc_VVV <"$dst.w += vmpyie($src1.w,$src2.h)">,
1388     V6_vmpyiewh_acc_enc;
1389defm V6_vmpyiewuh_acc :
1390     T_HVX_vmpyacc_VVV <"$dst.w += vmpyie($src1.w,$src2.uh)">,
1391     V6_vmpyiewuh_acc_enc;
1392defm V6_vmpyih_acc :
1393     T_HVX_vmpyacc_VVV <"$dst.h += vmpyi($src1.h,$src2.h)">, V6_vmpyih_acc_enc;
1394defm V6_vmpyowh_rnd_sacc :
1395     T_HVX_vmpyacc_VVV <"$dst.w += vmpyo($src1.w,$src2.h):<<1:rnd:sat:shift">,
1396     V6_vmpyowh_rnd_sacc_enc;
1397defm V6_vmpyowh_sacc :
1398     T_HVX_vmpyacc_VVV <"$dst.w += vmpyo($src1.w,$src2.h):<<1:sat:shift">,
1399     V6_vmpyowh_sacc_enc;
1400defm V6_vmpyubv_acc :
1401     T_HVX_vmpyacc_WVV <"$dst.uh += vmpy($src1.ub,$src2.ub)">,
1402     V6_vmpyubv_acc_enc;
1403defm V6_vmpyuhv_acc :
1404     T_HVX_vmpyacc_WVV <"$dst.uw += vmpy($src1.uh,$src2.uh)">,
1405     V6_vmpyuhv_acc_enc;
1406defm V6_vrmpybusv_acc :
1407     T_HVX_vmpyacc_VVV <"$dst.w += vrmpy($src1.ub,$src2.b)">,
1408     V6_vrmpybusv_acc_enc;
1409defm V6_vrmpybv_acc :
1410     T_HVX_vmpyacc_VVV <"$dst.w += vrmpy($src1.b,$src2.b)">, V6_vrmpybv_acc_enc;
1411defm V6_vrmpyubv_acc :
1412     T_HVX_vmpyacc_VVV <"$dst.uw += vrmpy($src1.ub,$src2.ub)">,
1413     V6_vrmpyubv_acc_enc;
1414
1415
1416class T_HVX_vcmp <string asmString, RegisterClass RCout, RegisterClass RCin>
1417  : CVI_VA_Resource1 <(outs RCout:$dst),
1418                      (ins RCout:$_src_, RCin:$src1, RCin:$src2), asmString,
1419                      [], "$dst = $_src_" > {
1420  let Itinerary = CVI_VA;
1421  let Type = TypeCVI_VA;
1422}
1423
1424multiclass T_HVX_vcmp <string asmString> {
1425  def NAME : T_HVX_vcmp <asmString, VecPredRegs, VectorRegs>;
1426  let isCodeGenOnly = 1 in
1427  def NAME#_128B : T_HVX_vcmp <asmString, VecPredRegs128B, VectorRegs128B>;
1428}
1429
1430defm V6_veqb_and :
1431     T_HVX_vcmp <"$dst &= vcmp.eq($src1.b,$src2.b)">, V6_veqb_and_enc;
1432defm V6_veqh_and :
1433     T_HVX_vcmp <"$dst &= vcmp.eq($src1.h,$src2.h)">, V6_veqh_and_enc;
1434defm V6_veqw_and :
1435     T_HVX_vcmp <"$dst &= vcmp.eq($src1.w,$src2.w)">, V6_veqw_and_enc;
1436defm V6_vgtb_and :
1437     T_HVX_vcmp <"$dst &= vcmp.gt($src1.b,$src2.b)">, V6_vgtb_and_enc;
1438defm V6_vgth_and :
1439     T_HVX_vcmp <"$dst &= vcmp.gt($src1.h,$src2.h)">, V6_vgth_and_enc;
1440defm V6_vgtw_and :
1441     T_HVX_vcmp <"$dst &= vcmp.gt($src1.w,$src2.w)">, V6_vgtw_and_enc;
1442defm V6_vgtub_and :
1443     T_HVX_vcmp <"$dst &= vcmp.gt($src1.ub,$src2.ub)">, V6_vgtub_and_enc;
1444defm V6_vgtuh_and :
1445     T_HVX_vcmp <"$dst &= vcmp.gt($src1.uh,$src2.uh)">, V6_vgtuh_and_enc;
1446defm V6_vgtuw_and :
1447     T_HVX_vcmp <"$dst &= vcmp.gt($src1.uw,$src2.uw)">, V6_vgtuw_and_enc;
1448defm V6_veqb_or :
1449     T_HVX_vcmp <"$dst |= vcmp.eq($src1.b,$src2.b)">, V6_veqb_or_enc;
1450defm V6_veqh_or :
1451     T_HVX_vcmp <"$dst |= vcmp.eq($src1.h,$src2.h)">, V6_veqh_or_enc;
1452defm V6_veqw_or :
1453     T_HVX_vcmp <"$dst |= vcmp.eq($src1.w,$src2.w)">, V6_veqw_or_enc;
1454defm V6_vgtb_or :
1455     T_HVX_vcmp <"$dst |= vcmp.gt($src1.b,$src2.b)">, V6_vgtb_or_enc;
1456defm V6_vgth_or :
1457     T_HVX_vcmp <"$dst |= vcmp.gt($src1.h,$src2.h)">, V6_vgth_or_enc;
1458defm V6_vgtw_or :
1459     T_HVX_vcmp <"$dst |= vcmp.gt($src1.w,$src2.w)">, V6_vgtw_or_enc;
1460defm V6_vgtub_or :
1461     T_HVX_vcmp <"$dst |= vcmp.gt($src1.ub,$src2.ub)">, V6_vgtub_or_enc;
1462defm V6_vgtuh_or :
1463     T_HVX_vcmp <"$dst |= vcmp.gt($src1.uh,$src2.uh)">, V6_vgtuh_or_enc;
1464defm V6_vgtuw_or :
1465     T_HVX_vcmp <"$dst |= vcmp.gt($src1.uw,$src2.uw)">, V6_vgtuw_or_enc;
1466defm V6_veqb_xor :
1467     T_HVX_vcmp <"$dst ^= vcmp.eq($src1.b,$src2.b)">, V6_veqb_xor_enc;
1468defm V6_veqh_xor :
1469     T_HVX_vcmp <"$dst ^= vcmp.eq($src1.h,$src2.h)">, V6_veqh_xor_enc;
1470defm V6_veqw_xor :
1471     T_HVX_vcmp <"$dst ^= vcmp.eq($src1.w,$src2.w)">, V6_veqw_xor_enc;
1472defm V6_vgtb_xor :
1473     T_HVX_vcmp <"$dst ^= vcmp.gt($src1.b,$src2.b)">, V6_vgtb_xor_enc;
1474defm V6_vgth_xor :
1475     T_HVX_vcmp <"$dst ^= vcmp.gt($src1.h,$src2.h)">, V6_vgth_xor_enc;
1476defm V6_vgtw_xor :
1477     T_HVX_vcmp <"$dst ^= vcmp.gt($src1.w,$src2.w)">, V6_vgtw_xor_enc;
1478defm V6_vgtub_xor :
1479     T_HVX_vcmp <"$dst ^= vcmp.gt($src1.ub,$src2.ub)">, V6_vgtub_xor_enc;
1480defm V6_vgtuh_xor :
1481     T_HVX_vcmp <"$dst ^= vcmp.gt($src1.uh,$src2.uh)">, V6_vgtuh_xor_enc;
1482defm V6_vgtuw_xor :
1483     T_HVX_vcmp <"$dst ^= vcmp.gt($src1.uw,$src2.uw)">, V6_vgtuw_xor_enc;
1484
1485defm V6_vminub :
1486     T_HVX_alu_VV <"$dst.ub = vmin($src1.ub,$src2.ub)">, V6_vminub_enc;
1487defm V6_vminuh :
1488     T_HVX_alu_VV <"$dst.uh = vmin($src1.uh,$src2.uh)">, V6_vminuh_enc;
1489defm V6_vminh :
1490     T_HVX_alu_VV <"$dst.h = vmin($src1.h,$src2.h)">, V6_vminh_enc;
1491defm V6_vminw :
1492     T_HVX_alu_VV <"$dst.w = vmin($src1.w,$src2.w)">, V6_vminw_enc;
1493defm V6_vmaxub :
1494     T_HVX_alu_VV <"$dst.ub = vmax($src1.ub,$src2.ub)">, V6_vmaxub_enc;
1495defm V6_vmaxuh :
1496     T_HVX_alu_VV <"$dst.uh = vmax($src1.uh,$src2.uh)">, V6_vmaxuh_enc;
1497defm V6_vmaxh :
1498     T_HVX_alu_VV <"$dst.h = vmax($src1.h,$src2.h)">, V6_vmaxh_enc;
1499defm V6_vmaxw :
1500     T_HVX_alu_VV <"$dst.w = vmax($src1.w,$src2.w)">, V6_vmaxw_enc;
1501defm V6_vshuffeb :
1502     T_HVX_alu_VV <"$dst.b = vshuffe($src1.b,$src2.b)">, V6_vshuffeb_enc;
1503defm V6_vshuffob :
1504     T_HVX_alu_VV <"$dst.b = vshuffo($src1.b,$src2.b)">, V6_vshuffob_enc;
1505defm V6_vshufeh :
1506     T_HVX_alu_VV <"$dst.h = vshuffe($src1.h,$src2.h)">, V6_vshufeh_enc;
1507defm V6_vshufoh :
1508     T_HVX_alu_VV <"$dst.h = vshuffo($src1.h,$src2.h)">, V6_vshufoh_enc;
1509
1510let Itinerary = CVI_VX_DV, Type = TypeCVI_VX_DV in {
1511defm V6_vmpyowh_rnd :
1512     T_HVX_alu_VV <"$dst.w = vmpyo($src1.w,$src2.h):<<1:rnd:sat">,
1513     V6_vmpyowh_rnd_enc;
1514defm V6_vmpyiewuh :
1515     T_HVX_alu_VV <"$dst.w = vmpyie($src1.w,$src2.uh)">, V6_vmpyiewuh_enc;
1516defm V6_vmpyewuh :
1517     T_HVX_alu_VV <"$dst.w = vmpye($src1.w,$src2.uh)">, V6_vmpyewuh_enc;
1518defm V6_vmpyowh :
1519     T_HVX_alu_VV <"$dst.w = vmpyo($src1.w,$src2.h):<<1:sat">, V6_vmpyowh_enc;
1520defm V6_vmpyiowh :
1521     T_HVX_alu_VV <"$dst.w = vmpyio($src1.w,$src2.h)">, V6_vmpyiowh_enc;
1522}
1523let Itinerary = CVI_VX, Type = TypeCVI_VX in
1524defm V6_vmpyieoh :
1525     T_HVX_alu_VV <"$dst.w = vmpyieo($src1.h,$src2.h)">, V6_vmpyieoh_enc;
1526
1527let Itinerary = CVI_VA_DV, Type = TypeCVI_VA_DV in {
1528defm V6_vshufoeh :
1529     T_HVX_alu_WV <"$dst.h = vshuffoe($src1.h,$src2.h)">, V6_vshufoeh_enc;
1530defm V6_vshufoeb :
1531     T_HVX_alu_WV <"$dst.b = vshuffoe($src1.b,$src2.b)">, V6_vshufoeb_enc;
1532}
1533
1534let isRegSequence = 1, Itinerary = CVI_VA_DV, Type = TypeCVI_VA_DV in
1535defm V6_vcombine :
1536     T_HVX_alu_WV <"$dst = vcombine($src1,$src2)">, V6_vcombine_enc;
1537
1538def SDTHexagonVCOMBINE: SDTypeProfile<1, 2, [SDTCisSameAs<1, 2>,
1539      SDTCisSubVecOfVec<1, 0>]>;
1540
1541def HexagonVCOMBINE: SDNode<"HexagonISD::VCOMBINE", SDTHexagonVCOMBINE>;
1542
1543def: Pat<(v32i32 (HexagonVCOMBINE (v16i32 VectorRegs:$Vs),
1544                                  (v16i32 VectorRegs:$Vt))),
1545         (V6_vcombine VectorRegs:$Vs, VectorRegs:$Vt)>,
1546         Requires<[UseHVXSgl]>;
1547def: Pat<(v64i32 (HexagonVCOMBINE (v32i32 VecDblRegs:$Vs),
1548                                  (v32i32 VecDblRegs:$Vt))),
1549         (V6_vcombine_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
1550         Requires<[UseHVXDbl]>;
1551
1552let Itinerary = CVI_VINLANESAT, Type = TypeCVI_VINLANESAT in {
1553defm V6_vsathub :
1554     T_HVX_alu_VV <"$dst.ub = vsat($src1.h,$src2.h)">, V6_vsathub_enc;
1555defm V6_vsatwh :
1556     T_HVX_alu_VV <"$dst.h = vsat($src1.w,$src2.w)">, V6_vsatwh_enc;
1557}
1558
1559let Itinerary = CVI_VS, Type = TypeCVI_VS in {
1560defm V6_vroundwh :
1561     T_HVX_alu_VV <"$dst.h = vround($src1.w,$src2.w):sat">, V6_vroundwh_enc;
1562defm V6_vroundwuh :
1563     T_HVX_alu_VV <"$dst.uh = vround($src1.w,$src2.w):sat">, V6_vroundwuh_enc;
1564defm V6_vroundhb :
1565     T_HVX_alu_VV <"$dst.b = vround($src1.h,$src2.h):sat">, V6_vroundhb_enc;
1566defm V6_vroundhub :
1567     T_HVX_alu_VV <"$dst.ub = vround($src1.h,$src2.h):sat">, V6_vroundhub_enc;
1568defm V6_vasrwv :
1569     T_HVX_alu_VV <"$dst.w = vasr($src1.w,$src2.w)">, V6_vasrwv_enc;
1570defm V6_vlsrwv :
1571     T_HVX_alu_VV <"$dst.w = vlsr($src1.w,$src2.w)">, V6_vlsrwv_enc;
1572defm V6_vlsrhv :
1573     T_HVX_alu_VV <"$dst.h = vlsr($src1.h,$src2.h)">, V6_vlsrhv_enc;
1574defm V6_vasrhv :
1575     T_HVX_alu_VV <"$dst.h = vasr($src1.h,$src2.h)">, V6_vasrhv_enc;
1576defm V6_vaslwv :
1577     T_HVX_alu_VV <"$dst.w = vasl($src1.w,$src2.w)">, V6_vaslwv_enc;
1578defm V6_vaslhv :
1579     T_HVX_alu_VV <"$dst.h = vasl($src1.h,$src2.h)">, V6_vaslhv_enc;
1580}
1581
1582defm V6_vaddb :
1583     T_HVX_alu_VV <"$dst.b = vadd($src1.b,$src2.b)">, V6_vaddb_enc;
1584defm V6_vaddh :
1585     T_HVX_alu_VV <"$dst.h = vadd($src1.h,$src2.h)">, V6_vaddh_enc;
1586
1587let Itinerary = CVI_VP, Type = TypeCVI_VP in {
1588defm V6_vdelta :
1589     T_HVX_alu_VV <"$dst = vdelta($src1,$src2)">, V6_vdelta_enc;
1590defm V6_vrdelta :
1591     T_HVX_alu_VV <"$dst = vrdelta($src1,$src2)">, V6_vrdelta_enc;
1592defm V6_vdealb4w :
1593     T_HVX_alu_VV <"$dst.b = vdeale($src1.b,$src2.b)">, V6_vdealb4w_enc;
1594defm V6_vpackeb :
1595     T_HVX_alu_VV <"$dst.b = vpacke($src1.h,$src2.h)">, V6_vpackeb_enc;
1596defm V6_vpackeh :
1597     T_HVX_alu_VV <"$dst.h = vpacke($src1.w,$src2.w)">, V6_vpackeh_enc;
1598defm V6_vpackhub_sat :
1599     T_HVX_alu_VV <"$dst.ub = vpack($src1.h,$src2.h):sat">, V6_vpackhub_sat_enc;
1600defm V6_vpackhb_sat :
1601     T_HVX_alu_VV <"$dst.b = vpack($src1.h,$src2.h):sat">, V6_vpackhb_sat_enc;
1602defm V6_vpackwuh_sat :
1603     T_HVX_alu_VV <"$dst.uh = vpack($src1.w,$src2.w):sat">, V6_vpackwuh_sat_enc;
1604defm V6_vpackwh_sat :
1605     T_HVX_alu_VV <"$dst.h = vpack($src1.w,$src2.w):sat">, V6_vpackwh_sat_enc;
1606defm V6_vpackob :
1607     T_HVX_alu_VV <"$dst.b = vpacko($src1.h,$src2.h)">, V6_vpackob_enc;
1608defm V6_vpackoh :
1609     T_HVX_alu_VV <"$dst.h = vpacko($src1.w,$src2.w)">, V6_vpackoh_enc;
1610}
1611
1612let hasNewValue = 1, hasSideEffects = 0 in
1613class T_HVX_condALU <string asmString, RegisterClass RC1, RegisterClass RC2>
1614  : CVI_VA_Resource1 <(outs RC2:$dst),
1615                      (ins RC1:$src1, RC2:$_src_, RC2:$src2), asmString,
1616                      [], "$dst = $_src_" > {
1617  let Itinerary = CVI_VA;
1618  let Type = TypeCVI_VA;
1619}
1620
1621multiclass T_HVX_condALU <string asmString> {
1622  def NAME : T_HVX_condALU <asmString, VecPredRegs, VectorRegs>;
1623  let isCodeGenOnly = 1 in
1624  def NAME#_128B : T_HVX_condALU <asmString, VecPredRegs128B, VectorRegs128B>;
1625}
1626
1627defm V6_vaddbq  : T_HVX_condALU <"if ($src1) $dst.b += $src2.b">,
1628                  V6_vaddbq_enc;
1629defm V6_vaddhq  : T_HVX_condALU <"if ($src1) $dst.h += $src2.h">,
1630                  V6_vaddhq_enc;
1631defm V6_vaddwq  : T_HVX_condALU <"if ($src1) $dst.w += $src2.w">,
1632                  V6_vaddwq_enc;
1633defm V6_vsubbq  : T_HVX_condALU <"if ($src1) $dst.b -= $src2.b">,
1634                  V6_vsubbq_enc;
1635defm V6_vsubhq  : T_HVX_condALU <"if ($src1) $dst.h -= $src2.h">,
1636                  V6_vsubhq_enc;
1637defm V6_vsubwq  : T_HVX_condALU <"if ($src1) $dst.w -= $src2.w">,
1638                  V6_vsubwq_enc;
1639defm V6_vaddbnq : T_HVX_condALU <"if (!$src1) $dst.b += $src2.b">,
1640                  V6_vaddbnq_enc;
1641defm V6_vaddhnq : T_HVX_condALU <"if (!$src1) $dst.h += $src2.h">,
1642                  V6_vaddhnq_enc;
1643defm V6_vaddwnq : T_HVX_condALU <"if (!$src1) $dst.w += $src2.w">,
1644                  V6_vaddwnq_enc;
1645defm V6_vsubbnq : T_HVX_condALU <"if (!$src1) $dst.b -= $src2.b">,
1646                  V6_vsubbnq_enc;
1647defm V6_vsubhnq : T_HVX_condALU <"if (!$src1) $dst.h -= $src2.h">,
1648                  V6_vsubhnq_enc;
1649defm V6_vsubwnq : T_HVX_condALU <"if (!$src1) $dst.w -= $src2.w">,
1650                  V6_vsubwnq_enc;
1651
1652let hasNewValue = 1 in
1653class T_HVX_alu_2op <string asmString, InstrItinClass itin,
1654                 RegisterClass RCout, RegisterClass RCin>
1655  : CVI_VA_Resource1 <(outs RCout:$dst), (ins RCin:$src1),
1656    asmString >{
1657  let Itinerary = itin;
1658  let Type = !cast<IType>("Type"#itin);
1659}
1660
1661multiclass T_HVX_alu_2op <string asmString, RegisterClass RCout,
1662           RegisterClass RCin, InstrItinClass itin> {
1663  def NAME : T_HVX_alu_2op <asmString, itin, RCout, RCin>;
1664  let isCodeGenOnly = 1 in
1665  def NAME#_128B : T_HVX_alu_2op <asmString, itin,
1666                              !cast<RegisterClass>(RCout#"128B"),
1667                              !cast<RegisterClass>(RCin#"128B")>;
1668}
1669
1670let hasNewValue = 1 in
1671multiclass T_HVX_alu_2op_VV <string asmString>:
1672  T_HVX_alu_2op <asmString, VectorRegs, VectorRegs, CVI_VA>;
1673
1674multiclass T_HVX_alu_2op_WV <string asmString>:
1675  T_HVX_alu_2op <asmString, VecDblRegs, VectorRegs, CVI_VA_DV>;
1676
1677
1678defm V6_vabsh     : T_HVX_alu_2op_VV <"$dst.h = vabs($src1.h)">,
1679                    V6_vabsh_enc;
1680defm V6_vabsw     : T_HVX_alu_2op_VV <"$dst.w = vabs($src1.w)">,
1681                    V6_vabsw_enc;
1682defm V6_vabsh_sat : T_HVX_alu_2op_VV <"$dst.h = vabs($src1.h):sat">,
1683                    V6_vabsh_sat_enc;
1684defm V6_vabsw_sat : T_HVX_alu_2op_VV <"$dst.w = vabs($src1.w):sat">,
1685                    V6_vabsw_sat_enc;
1686defm V6_vnot      : T_HVX_alu_2op_VV <"$dst = vnot($src1)">,
1687                    V6_vnot_enc;
1688defm V6_vassign   : T_HVX_alu_2op_VV <"$dst = $src1">,
1689                    V6_vassign_enc;
1690
1691defm V6_vzb       : T_HVX_alu_2op_WV <"$dst.uh = vzxt($src1.ub)">,
1692                    V6_vzb_enc;
1693defm V6_vzh       : T_HVX_alu_2op_WV <"$dst.uw = vzxt($src1.uh)">,
1694                    V6_vzh_enc;
1695defm V6_vsb       : T_HVX_alu_2op_WV <"$dst.h = vsxt($src1.b)">,
1696                    V6_vsb_enc;
1697defm V6_vsh       : T_HVX_alu_2op_WV <"$dst.w = vsxt($src1.h)">,
1698                    V6_vsh_enc;
1699
1700let Itinerary = CVI_VP, Type = TypeCVI_VP in {
1701defm V6_vdealh    : T_HVX_alu_2op_VV <"$dst.h = vdeal($src1.h)">,
1702                    V6_vdealh_enc;
1703defm V6_vdealb    : T_HVX_alu_2op_VV <"$dst.b = vdeal($src1.b)">,
1704                    V6_vdealb_enc;
1705defm V6_vshuffh   : T_HVX_alu_2op_VV <"$dst.h = vshuff($src1.h)">,
1706                    V6_vshuffh_enc;
1707defm V6_vshuffb   : T_HVX_alu_2op_VV <"$dst.b = vshuff($src1.b)">,
1708                    V6_vshuffb_enc;
1709}
1710
1711let Itinerary = CVI_VP_VS, Type = TypeCVI_VP_VS in {
1712defm V6_vunpackub : T_HVX_alu_2op_WV <"$dst.uh = vunpack($src1.ub)">,
1713                    V6_vunpackub_enc;
1714defm V6_vunpackuh : T_HVX_alu_2op_WV <"$dst.uw = vunpack($src1.uh)">,
1715                    V6_vunpackuh_enc;
1716defm V6_vunpackb  : T_HVX_alu_2op_WV <"$dst.h = vunpack($src1.b)">,
1717                    V6_vunpackb_enc;
1718defm V6_vunpackh  : T_HVX_alu_2op_WV <"$dst.w = vunpack($src1.h)">,
1719                    V6_vunpackh_enc;
1720}
1721
1722let Itinerary = CVI_VS, Type = TypeCVI_VS in {
1723defm V6_vcl0w     : T_HVX_alu_2op_VV <"$dst.uw = vcl0($src1.uw)">,
1724                    V6_vcl0w_enc;
1725defm V6_vcl0h     : T_HVX_alu_2op_VV <"$dst.uh = vcl0($src1.uh)">,
1726                    V6_vcl0h_enc;
1727defm V6_vnormamtw : T_HVX_alu_2op_VV <"$dst.w = vnormamt($src1.w)">,
1728                    V6_vnormamtw_enc;
1729defm V6_vnormamth : T_HVX_alu_2op_VV <"$dst.h = vnormamt($src1.h)">,
1730                    V6_vnormamth_enc;
1731defm V6_vpopcounth : T_HVX_alu_2op_VV <"$dst.h = vpopcount($src1.h)">,
1732                     V6_vpopcounth_enc;
1733}
1734
1735let isAccumulator = 1, hasNewValue = 1, Itinerary = CVI_VX_DV_LONG,
1736    Type = TypeCVI_VX_DV in
1737class T_HVX_vmpyacc2 <string asmString, RegisterClass RC>
1738  : CVI_VA_Resource1 <(outs RC:$dst),
1739                      (ins RC:$_src_, RC:$src1, IntRegs:$src2, u1Imm:$src3),
1740    asmString, [], "$dst = $_src_" > ;
1741
1742
1743multiclass T_HVX_vmpyacc2 <string asmString> {
1744  def NAME : T_HVX_vmpyacc2 <asmString, VecDblRegs>;
1745
1746  let isCodeGenOnly = 1 in
1747  def NAME#_128B : T_HVX_vmpyacc2 <asmString, VecDblRegs128B>;
1748}
1749
1750defm V6_vrmpybusi_acc :
1751     T_HVX_vmpyacc2<"$dst.w += vrmpy($src1.ub,$src2.b,#$src3)">,
1752     V6_vrmpybusi_acc_enc;
1753defm V6_vrsadubi_acc :
1754     T_HVX_vmpyacc2<"$dst.uw += vrsad($src1.ub,$src2.ub,#$src3)">,
1755     V6_vrsadubi_acc_enc;
1756defm V6_vrmpyubi_acc :
1757     T_HVX_vmpyacc2<"$dst.uw += vrmpy($src1.ub,$src2.ub,#$src3)">,
1758     V6_vrmpyubi_acc_enc;
1759
1760
1761let Itinerary = CVI_VX_DV_LONG, Type = TypeCVI_VX_DV, hasNewValue = 1 in
1762class T_HVX_vmpy2 <string asmString, RegisterClass RC>
1763  : CVI_VA_Resource1<(outs RC:$dst), (ins RC:$src1, IntRegs:$src2, u1Imm:$src3),
1764    asmString>;
1765
1766
1767multiclass T_HVX_vmpy2 <string asmString> {
1768  def NAME : T_HVX_vmpy2 <asmString, VecDblRegs>;
1769
1770  let isCodeGenOnly = 1 in
1771  def NAME#_128B : T_HVX_vmpy2 <asmString, VecDblRegs128B>;
1772}
1773
1774defm V6_vrmpybusi :
1775     T_HVX_vmpy2 <"$dst.w = vrmpy($src1.ub,$src2.b,#$src3)">, V6_vrmpybusi_enc;
1776defm V6_vrsadubi :
1777     T_HVX_vmpy2 <"$dst.uw = vrsad($src1.ub,$src2.ub,#$src3)">, V6_vrsadubi_enc;
1778defm V6_vrmpyubi :
1779     T_HVX_vmpy2 <"$dst.uw = vrmpy($src1.ub,$src2.ub,#$src3)">, V6_vrmpyubi_enc;
1780
1781
1782let Itinerary = CVI_VP_VS_LONG_EARLY, Type = TypeCVI_VP_VS,
1783    hasSideEffects = 0, hasNewValue2 = 1, opNewValue2 = 1 in
1784class T_HVX_perm <string asmString, RegisterClass RC>
1785  : CVI_VA_Resource1 <(outs RC:$_dst1_, RC:$_dst2_),
1786                      (ins RC:$src1, RC:$src2, IntRegs:$src3),
1787    asmString, [], "$_dst1_ = $src1, $_dst2_ = $src2" >;
1788
1789multiclass T_HVX_perm <string asmString> {
1790  def NAME : T_HVX_perm <asmString, VectorRegs>;
1791
1792  let isCodeGenOnly = 1 in
1793  def NAME#_128B : T_HVX_perm <asmString, VectorRegs128B>;
1794}
1795
1796let hasNewValue = 1, opNewValue = 0, hasNewValue2 = 1, opNewValue2 = 1 in {
1797  defm V6_vshuff : T_HVX_perm <"vshuff($src1,$src2,$src3)">, V6_vshuff_enc;
1798  defm V6_vdeal : T_HVX_perm <"vdeal($src1,$src2,$src3)">, V6_vdeal_enc;
1799}
1800
1801// Conditional vector move.
1802let isPredicated = 1, hasSideEffects = 0, hasNewValue = 1, opNewValue = 0 in
1803class T_HVX_cmov <bit isPredNot, RegisterClass RC>
1804  : CVI_VA_Resource1 <(outs RC:$dst), (ins PredRegs:$src1, RC:$src2),
1805    "if ("#!if(isPredNot, "!", "")#"$src1) $dst = $src2"> {
1806  let isPredicatedFalse = isPredNot;
1807}
1808
1809multiclass T_HVX_cmov <bit isPredNot = 0> {
1810  def NAME : T_HVX_cmov <isPredNot, VectorRegs>;
1811
1812  let isCodeGenOnly = 1 in
1813  def NAME#_128B : T_HVX_cmov <isPredNot, VectorRegs128B>;
1814}
1815
1816defm V6_vcmov : T_HVX_cmov, V6_vcmov_enc;
1817defm V6_vncmov : T_HVX_cmov<1>, V6_vncmov_enc;
1818
1819// Conditional vector combine.
1820let Itinerary = CVI_VA_DV, Type = TypeCVI_VA_DV, isPredicated = 1,
1821    hasSideEffects = 0, hasNewValue = 1, opNewValue = 0 in
1822class T_HVX_ccombine <bit isPredNot, RegisterClass RCout, RegisterClass RCin>
1823  : CVI_VA_Resource1 < (outs RCout:$dst),
1824    (ins PredRegs:$src1, RCin:$src2, RCin:$src3),
1825    "if ("#!if(isPredNot, "!", "")#"$src1) $dst = vcombine($src2,$src3)"> {
1826  let isPredicatedFalse = isPredNot;
1827}
1828
1829multiclass T_HVX_ccombine <bit isPredNot = 0> {
1830  def NAME : T_HVX_ccombine <isPredNot, VecDblRegs, VectorRegs>;
1831
1832  let isCodeGenOnly = 1 in
1833  def NAME#_128B : T_HVX_ccombine <isPredNot, VecDblRegs128B, VectorRegs128B>;
1834}
1835
1836defm V6_vccombine : T_HVX_ccombine, V6_vccombine_enc;
1837defm V6_vnccombine : T_HVX_ccombine<1>, V6_vnccombine_enc;
1838
1839let hasNewValue = 1 in
1840class T_HVX_shift <string asmString, RegisterClass RCout, RegisterClass RCin>
1841  : CVI_VX_DV_Resource1<(outs RCout:$dst),
1842    (ins RCin:$src1, RCin:$src2, IntRegsLow8:$src3),
1843    asmString >;
1844
1845multiclass T_HVX_shift <string asmString, RegisterClass RCout,
1846                        RegisterClass RCin> {
1847  def NAME : T_HVX_shift <asmString, RCout, RCin>;
1848  let isCodeGenOnly = 1 in
1849  def NAME#_128B : T_HVX_shift <asmString, !cast<RegisterClass>(RCout#"128B"),
1850                                           !cast<RegisterClass>(RCin#"128B")>;
1851}
1852
1853multiclass T_HVX_shift_VV <string asmString>:
1854  T_HVX_shift <asmString, VectorRegs, VectorRegs>;
1855
1856multiclass T_HVX_shift_WV <string asmString>:
1857  T_HVX_shift <asmString, VecDblRegs, VectorRegs>;
1858
1859let Itinerary = CVI_VP_LONG, Type = TypeCVI_VP in {
1860defm V6_valignb :
1861     T_HVX_shift_VV <"$dst = valign($src1,$src2,$src3)">, V6_valignb_enc;
1862defm V6_vlalignb :
1863     T_HVX_shift_VV <"$dst = vlalign($src1,$src2,$src3)">, V6_vlalignb_enc;
1864}
1865
1866let Itinerary = CVI_VS, Type = TypeCVI_VS in {
1867defm V6_vasrwh :
1868     T_HVX_shift_VV <"$dst.h = vasr($src1.w,$src2.w,$src3)">, V6_vasrwh_enc;
1869defm V6_vasrwhsat :
1870     T_HVX_shift_VV <"$dst.h = vasr($src1.w,$src2.w,$src3):sat">,
1871     V6_vasrwhsat_enc;
1872defm V6_vasrwhrndsat :
1873     T_HVX_shift_VV <"$dst.h = vasr($src1.w,$src2.w,$src3):rnd:sat">,
1874     V6_vasrwhrndsat_enc;
1875defm V6_vasrwuhsat :
1876     T_HVX_shift_VV <"$dst.uh = vasr($src1.w,$src2.w,$src3):sat">,
1877     V6_vasrwuhsat_enc;
1878defm V6_vasrhubsat :
1879     T_HVX_shift_VV <"$dst.ub = vasr($src1.h,$src2.h,$src3):sat">,
1880     V6_vasrhubsat_enc;
1881defm V6_vasrhubrndsat :
1882     T_HVX_shift_VV <"$dst.ub = vasr($src1.h,$src2.h,$src3):rnd:sat">,
1883     V6_vasrhubrndsat_enc;
1884defm V6_vasrhbrndsat :
1885     T_HVX_shift_VV <"$dst.b = vasr($src1.h,$src2.h,$src3):rnd:sat">,
1886     V6_vasrhbrndsat_enc;
1887}
1888
1889// Assembler mapped -- alias?
1890//defm V6_vtran2x2vdd : T_HVX_shift_VV <"">, V6_vtran2x2vdd_enc;
1891let Itinerary = CVI_VP_VS_LONG, Type = TypeCVI_VP_VS in {
1892defm V6_vshuffvdd :
1893     T_HVX_shift_WV <"$dst = vshuff($src1,$src2,$src3)">, V6_vshuffvdd_enc;
1894defm V6_vdealvdd :
1895     T_HVX_shift_WV <"$dst = vdeal($src1,$src2,$src3)">, V6_vdealvdd_enc;
1896}
1897
1898let hasNewValue = 1, Itinerary = CVI_VP_VS_LONG, Type = TypeCVI_VP_VS in
1899class T_HVX_unpack <string asmString, RegisterClass RCout, RegisterClass RCin>
1900  : CVI_VX_DV_Resource1<(outs RCout:$dst), (ins RCout:$_src_, RCin:$src1),
1901    asmString, [], "$dst = $_src_">;
1902
1903multiclass T_HVX_unpack <string asmString> {
1904  def NAME : T_HVX_unpack <asmString, VecDblRegs, VectorRegs>;
1905  let isCodeGenOnly = 1 in
1906  def NAME#_128B : T_HVX_unpack <asmString, VecDblRegs128B, VectorRegs128B>;
1907}
1908
1909defm V6_vunpackob : T_HVX_unpack <"$dst.h |= vunpacko($src1.b)">, V6_vunpackob_enc;
1910defm V6_vunpackoh : T_HVX_unpack <"$dst.w |= vunpacko($src1.h)">, V6_vunpackoh_enc;
1911
1912let Itinerary = CVI_VP_LONG, Type = TypeCVI_VP, hasNewValue = 1,
1913    hasSideEffects = 0 in
1914class T_HVX_valign <string asmString, RegisterClass RC>
1915  : CVI_VA_Resource1<(outs RC:$dst), (ins RC:$src1, RC:$src2, u3Imm:$src3),
1916    asmString>;
1917
1918multiclass T_HVX_valign <string asmString> {
1919  def NAME : T_HVX_valign <asmString, VectorRegs>;
1920
1921  let isCodeGenOnly = 1 in
1922  def NAME#_128B : T_HVX_valign <asmString, VectorRegs128B>;
1923}
1924
1925defm V6_valignbi :
1926     T_HVX_valign <"$dst = valign($src1,$src2,#$src3)">, V6_valignbi_enc;
1927defm V6_vlalignbi :
1928     T_HVX_valign <"$dst = vlalign($src1,$src2,#$src3)">, V6_vlalignbi_enc;
1929
1930let Itinerary = CVI_VA_DV, Type = TypeCVI_VA_DV in
1931class T_HVX_predAlu <string asmString, RegisterClass RC>
1932  : CVI_VA_Resource1<(outs RC:$dst), (ins RC:$src1, RC:$src2),
1933    asmString>;
1934
1935multiclass T_HVX_predAlu <string asmString> {
1936  def NAME : T_HVX_predAlu <asmString, VecPredRegs>;
1937
1938  let isCodeGenOnly = 1 in
1939  def NAME#_128B : T_HVX_predAlu <asmString, VecPredRegs128B>;
1940}
1941
1942defm V6_pred_and  : T_HVX_predAlu <"$dst = and($src1,$src2)">, V6_pred_and_enc;
1943defm V6_pred_or   : T_HVX_predAlu <"$dst = or($src1,$src2)">, V6_pred_or_enc;
1944defm V6_pred_xor  : T_HVX_predAlu <"$dst = xor($src1,$src2)">, V6_pred_xor_enc;
1945defm V6_pred_or_n : T_HVX_predAlu <"$dst = or($src1,!$src2)">, V6_pred_or_n_enc;
1946defm V6_pred_and_n :
1947     T_HVX_predAlu <"$dst = and($src1,!$src2)">, V6_pred_and_n_enc;
1948
1949let Itinerary = CVI_VA, Type = TypeCVI_VA in
1950class T_HVX_prednot <RegisterClass RC>
1951  : CVI_VA_Resource1<(outs RC:$dst), (ins RC:$src1),
1952    "$dst = not($src1)">, V6_pred_not_enc;
1953
1954def V6_pred_not : T_HVX_prednot <VecPredRegs>;
1955let isCodeGenOnly =  1 in
1956def V6_pred_not_128B : T_HVX_prednot <VecPredRegs128B>;
1957
1958let Itinerary = CVI_VA, Type = TypeCVI_VA in
1959class T_HVX_vcmp2 <string asmString, RegisterClass RCout, RegisterClass RCin>
1960  : CVI_VA_Resource1 <(outs RCout:$dst), (ins RCin:$src1, RCin:$src2),
1961    asmString >;
1962
1963multiclass T_HVX_vcmp2 <string asmString> {
1964  def NAME : T_HVX_vcmp2 <asmString, VecPredRegs, VectorRegs>;
1965  let isCodeGenOnly = 1 in
1966  def NAME#_128B : T_HVX_vcmp2 <asmString, VecPredRegs128B, VectorRegs128B>;
1967}
1968
1969defm V6_veqb : T_HVX_vcmp2  <"$dst = vcmp.eq($src1.b,$src2.b)">, V6_veqb_enc;
1970defm V6_veqh : T_HVX_vcmp2  <"$dst = vcmp.eq($src1.h,$src2.h)">, V6_veqh_enc;
1971defm V6_veqw : T_HVX_vcmp2  <"$dst = vcmp.eq($src1.w,$src2.w)">, V6_veqw_enc;
1972defm V6_vgtb : T_HVX_vcmp2  <"$dst = vcmp.gt($src1.b,$src2.b)">, V6_vgtb_enc;
1973defm V6_vgth : T_HVX_vcmp2  <"$dst = vcmp.gt($src1.h,$src2.h)">, V6_vgth_enc;
1974defm V6_vgtw : T_HVX_vcmp2  <"$dst = vcmp.gt($src1.w,$src2.w)">, V6_vgtw_enc;
1975defm V6_vgtub : T_HVX_vcmp2 <"$dst = vcmp.gt($src1.ub,$src2.ub)">, V6_vgtub_enc;
1976defm V6_vgtuh : T_HVX_vcmp2 <"$dst = vcmp.gt($src1.uh,$src2.uh)">, V6_vgtuh_enc;
1977defm V6_vgtuw : T_HVX_vcmp2 <"$dst = vcmp.gt($src1.uw,$src2.uw)">, V6_vgtuw_enc;
1978
1979let isAccumulator = 1, hasNewValue = 1, hasSideEffects = 0 in
1980class T_V6_vandqrt_acc <RegisterClass RCout, RegisterClass RCin>
1981  : CVI_VX_Resource_late<(outs RCout:$dst),
1982    (ins RCout:$_src_, RCin:$src1, IntRegs:$src2),
1983    "$dst |= vand($src1,$src2)", [], "$dst = $_src_">, V6_vandqrt_acc_enc;
1984
1985def V6_vandqrt_acc : T_V6_vandqrt_acc <VectorRegs, VecPredRegs>;
1986let isCodeGenOnly = 1 in
1987def V6_vandqrt_acc_128B : T_V6_vandqrt_acc <VectorRegs128B, VecPredRegs128B>;
1988
1989let isAccumulator = 1 in
1990class T_V6_vandvrt_acc <RegisterClass RCout, RegisterClass RCin>
1991  : CVI_VX_Resource_late<(outs RCout:$dst),
1992    (ins RCout:$_src_, RCin:$src1, IntRegs:$src2),
1993    "$dst |= vand($src1,$src2)", [], "$dst = $_src_">, V6_vandvrt_acc_enc;
1994
1995def V6_vandvrt_acc : T_V6_vandvrt_acc <VecPredRegs, VectorRegs>;
1996let isCodeGenOnly = 1 in
1997def V6_vandvrt_acc_128B : T_V6_vandvrt_acc <VecPredRegs128B, VectorRegs128B>;
1998
1999let hasNewValue =  1, hasSideEffects = 0 in
2000class T_V6_vandqrt <RegisterClass RCout, RegisterClass RCin>
2001  : CVI_VX_Resource_late<(outs RCout:$dst),
2002    (ins RCin:$src1, IntRegs:$src2),
2003    "$dst = vand($src1,$src2)" >, V6_vandqrt_enc;
2004
2005def V6_vandqrt : T_V6_vandqrt <VectorRegs, VecPredRegs>;
2006let isCodeGenOnly = 1 in
2007def V6_vandqrt_128B : T_V6_vandqrt <VectorRegs128B, VecPredRegs128B>;
2008
2009let hasNewValue = 1, hasSideEffects = 0 in
2010class T_V6_lvsplatw <RegisterClass RC>
2011  : CVI_VX_Resource_late<(outs RC:$dst), (ins IntRegs:$src1),
2012    "$dst = vsplat($src1)" >, V6_lvsplatw_enc;
2013
2014def V6_lvsplatw : T_V6_lvsplatw <VectorRegs>;
2015let isCodeGenOnly = 1 in
2016def V6_lvsplatw_128B : T_V6_lvsplatw <VectorRegs128B>;
2017
2018
2019let hasNewValue = 1 in
2020class T_V6_vinsertwr <RegisterClass RC>
2021  : CVI_VX_Resource_late<(outs RC:$dst), (ins RC:$_src_, IntRegs:$src1),
2022    "$dst.w = vinsert($src1)", [], "$dst = $_src_">,
2023    V6_vinsertwr_enc;
2024
2025def V6_vinsertwr : T_V6_vinsertwr <VectorRegs>;
2026let isCodeGenOnly = 1 in
2027def V6_vinsertwr_128B : T_V6_vinsertwr <VectorRegs128B>;
2028
2029
2030let Itinerary = CVI_VP_LONG, Type = TypeCVI_VP in
2031class T_V6_pred_scalar2 <RegisterClass RC>
2032  : CVI_VA_Resource1<(outs RC:$dst), (ins IntRegs:$src1),
2033    "$dst = vsetq($src1)">, V6_pred_scalar2_enc;
2034
2035def V6_pred_scalar2 : T_V6_pred_scalar2 <VecPredRegs>;
2036let isCodeGenOnly = 1 in
2037def V6_pred_scalar2_128B : T_V6_pred_scalar2 <VecPredRegs128B>;
2038
2039class T_V6_vandvrt <RegisterClass RCout, RegisterClass RCin>
2040  : CVI_VX_Resource_late<(outs RCout:$dst), (ins RCin:$src1, IntRegs:$src2),
2041    "$dst = vand($src1,$src2)">, V6_vandvrt_enc;
2042
2043def V6_vandvrt : T_V6_vandvrt <VecPredRegs, VectorRegs>;
2044let isCodeGenOnly = 1 in
2045def V6_vandvrt_128B : T_V6_vandvrt <VecPredRegs128B, VectorRegs128B>;
2046
2047let validSubTargets = HasV60SubT in
2048class T_HVX_rol <string asmString, RegisterClass RC, Operand ImmOp >
2049  : SInst2 <(outs RC:$dst), (ins  RC:$src1, ImmOp:$src2), asmString>;
2050
2051class T_HVX_rol_R <string asmString>
2052  : T_HVX_rol <asmString, IntRegs, u5Imm>;
2053class T_HVX_rol_P <string asmString>
2054  : T_HVX_rol <asmString, DoubleRegs, u6Imm>;
2055
2056def S6_rol_i_p : T_HVX_rol_P <"$dst = rol($src1,#$src2)">, S6_rol_i_p_enc;
2057let hasNewValue = 1, opNewValue = 0 in
2058def S6_rol_i_r : T_HVX_rol_R <"$dst = rol($src1,#$src2)">, S6_rol_i_r_enc;
2059
2060let validSubTargets = HasV60SubT in
2061class T_HVX_rol_acc <string asmString, RegisterClass RC, Operand ImmOp>
2062  : SInst2 <(outs RC:$dst), (ins RC:$_src_, RC:$src1, ImmOp:$src2),
2063    asmString, [], "$dst = $_src_" >;
2064
2065class T_HVX_rol_acc_P <string asmString>
2066  : T_HVX_rol_acc <asmString, DoubleRegs, u6Imm>;
2067
2068class T_HVX_rol_acc_R <string asmString>
2069  : T_HVX_rol_acc <asmString, IntRegs, u5Imm>;
2070
2071def S6_rol_i_p_nac :
2072    T_HVX_rol_acc_P <"$dst -= rol($src1,#$src2)">, S6_rol_i_p_nac_enc;
2073def S6_rol_i_p_acc :
2074    T_HVX_rol_acc_P <"$dst += rol($src1,#$src2)">, S6_rol_i_p_acc_enc;
2075def S6_rol_i_p_and :
2076    T_HVX_rol_acc_P <"$dst &= rol($src1,#$src2)">, S6_rol_i_p_and_enc;
2077def S6_rol_i_p_or  :
2078    T_HVX_rol_acc_P <"$dst |= rol($src1,#$src2)">, S6_rol_i_p_or_enc;
2079def S6_rol_i_p_xacc :
2080    T_HVX_rol_acc_P<"$dst ^= rol($src1,#$src2)">, S6_rol_i_p_xacc_enc;
2081
2082let hasNewValue = 1, opNewValue = 0 in {
2083def S6_rol_i_r_nac :
2084    T_HVX_rol_acc_R <"$dst -= rol($src1,#$src2)">, S6_rol_i_r_nac_enc;
2085def S6_rol_i_r_acc :
2086    T_HVX_rol_acc_R <"$dst += rol($src1,#$src2)">, S6_rol_i_r_acc_enc;
2087def S6_rol_i_r_and :
2088    T_HVX_rol_acc_R <"$dst &= rol($src1,#$src2)">, S6_rol_i_r_and_enc;
2089def S6_rol_i_r_or :
2090    T_HVX_rol_acc_R <"$dst |= rol($src1,#$src2)">, S6_rol_i_r_or_enc;
2091def S6_rol_i_r_xacc :
2092    T_HVX_rol_acc_R <"$dst ^= rol($src1,#$src2)">, S6_rol_i_r_xacc_enc;
2093}
2094
2095let isSolo = 1, Itinerary = LD_tc_ld_SLOT0, Type = TypeLD in
2096class T_V6_extractw <RegisterClass RC>
2097  : LD1Inst <(outs IntRegs:$dst), (ins RC:$src1, IntRegs:$src2),
2098    "$dst = vextract($src1,$src2)">, V6_extractw_enc;
2099
2100def V6_extractw : T_V6_extractw <VectorRegs>;
2101let isCodeGenOnly = 1 in
2102def V6_extractw_128B : T_V6_extractw <VectorRegs128B>;
2103
2104let Itinerary = ST_tc_st_SLOT0, validSubTargets = HasV55SubT  in
2105class T_sys0op <string asmString>
2106  : ST1Inst <(outs), (ins), asmString>;
2107
2108let isSolo = 1, validSubTargets = HasV55SubT in {
2109def Y5_l2gunlock   : T_sys0op <"l2gunlock">, Y5_l2gunlock_enc;
2110def Y5_l2gclean    : T_sys0op <"l2gclean">, Y5_l2gclean_enc;
2111def Y5_l2gcleaninv : T_sys0op <"l2gcleaninv">, Y5_l2gcleaninv_enc;
2112}
2113
2114class T_sys1op <string asmString, RegisterClass RC>
2115  : ST1Inst <(outs), (ins RC:$src1), asmString>;
2116
2117class T_sys1op_R <string asmString> : T_sys1op <asmString, IntRegs>;
2118class T_sys1op_P <string asmString> : T_sys1op <asmString, DoubleRegs>;
2119
2120let isSoloAX = 1, validSubTargets = HasV55SubT in
2121def Y5_l2unlocka     : T_sys1op_R <"l2unlocka($src1)">, Y5_l2unlocka_enc;
2122
2123let isSolo = 1, validSubTargets = HasV60SubT in {
2124def Y6_l2gcleanpa    : T_sys1op_P <"l2gclean($src1)">, Y6_l2gcleanpa_enc;
2125def Y6_l2gcleaninvpa : T_sys1op_P <"l2gcleaninv($src1)">, Y6_l2gcleaninvpa_enc;
2126}
2127
2128let Itinerary = ST_tc_3stall_SLOT0, isPredicateLate = 1, isSoloAX = 1,
2129    validSubTargets = HasV55SubT in
2130def Y5_l2locka : ST1Inst <(outs PredRegs:$dst), (ins IntRegs:$src1),
2131  "$dst = l2locka($src1)">, Y5_l2locka_enc;
2132
2133// not defined on etc side. why?
2134// defm S2_cabacencbin : _VV <"Rdd=encbin(Rss,$src2,Pu)">, S2_cabacencbin_enc;
2135
2136let Defs = [USR_OVF], Itinerary = M_tc_3stall_SLOT23, isPredicateLate = 1,
2137    hasSideEffects = 0,
2138validSubTargets = HasV55SubT in
2139def A5_ACS : MInst2 <(outs DoubleRegs:$dst1, PredRegs:$dst2),
2140  (ins DoubleRegs:$_src_, DoubleRegs:$src1, DoubleRegs:$src2),
2141  "$dst1,$dst2 = vacsh($src1,$src2)", [],
2142  "$dst1 = $_src_" >, Requires<[HasV55T]>, A5_ACS_enc;
2143
2144let Itinerary = CVI_VA_DV, Type = TypeCVI_VA_DV, hasNewValue = 1,
2145    hasSideEffects = 0 in
2146class T_HVX_alu2 <string asmString, RegisterClass RCout, RegisterClass RCin1,
2147                  RegisterClass RCin2>
2148  : CVI_VA_Resource1<(outs RCout:$dst),
2149    (ins RCin1:$src1, RCin2:$src2, RCin2:$src3), asmString>;
2150
2151multiclass T_HVX_alu2 <string asmString, RegisterClass RC > {
2152  def NAME : T_HVX_alu2 <asmString, RC, VecPredRegs, VectorRegs>;
2153  let isCodeGenOnly = 1 in
2154  def NAME#_128B : T_HVX_alu2 <asmString, !cast<RegisterClass>(RC#"128B"),
2155                               VecPredRegs128B, VectorRegs128B>;
2156}
2157
2158multiclass T_HVX_alu2_V <string asmString> :
2159  T_HVX_alu2 <asmString, VectorRegs>;
2160
2161multiclass T_HVX_alu2_W <string asmString> :
2162  T_HVX_alu2 <asmString, VecDblRegs>;
2163
2164defm V6_vswap : T_HVX_alu2_W <"$dst = vswap($src1,$src2,$src3)">, V6_vswap_enc;
2165
2166let Itinerary = CVI_VA, Type = TypeCVI_VA, hasNewValue = 1,
2167    hasSideEffects = 0 in
2168defm V6_vmux  : T_HVX_alu2_V <"$dst = vmux($src1,$src2,$src3)">, V6_vmux_enc;
2169
2170class T_HVX_vlutb <string asmString, RegisterClass RCout, RegisterClass RCin>
2171  : CVI_VA_Resource1<(outs RCout:$dst),
2172    (ins RCin:$src1, RCin:$src2, IntRegsLow8:$src3), asmString>;
2173
2174multiclass T_HVX_vlutb <string asmString, RegisterClass RCout,
2175                        RegisterClass RCin> {
2176  def NAME : T_HVX_vlutb <asmString, RCout, RCin>;
2177  let isCodeGenOnly = 1 in
2178  def NAME#_128B : T_HVX_vlutb <asmString, !cast<RegisterClass>(RCout#"128B"),
2179                                           !cast<RegisterClass>(RCin#"128B")>;
2180}
2181
2182multiclass T_HVX_vlutb_V <string asmString> :
2183  T_HVX_vlutb <asmString, VectorRegs, VectorRegs>;
2184
2185multiclass T_HVX_vlutb_W <string asmString> :
2186  T_HVX_vlutb <asmString, VecDblRegs, VectorRegs>;
2187
2188let Itinerary = CVI_VP_VS_LONG, Type = TypeCVI_VP_VS, isAccumulator = 1 in
2189class T_HVX_vlutb_acc <string asmString, RegisterClass RCout,
2190                       RegisterClass RCin>
2191  : CVI_VA_Resource1<(outs RCout:$dst),
2192    (ins RCout:$_src_, RCin:$src1, RCin:$src2, IntRegsLow8:$src3),
2193    asmString, [], "$dst = $_src_">;
2194
2195multiclass T_HVX_vlutb_acc <string asmString, RegisterClass RCout,
2196                            RegisterClass RCin> {
2197  def NAME : T_HVX_vlutb_acc <asmString, RCout, RCin>;
2198  let isCodeGenOnly = 1 in
2199  def NAME#_128B : T_HVX_vlutb_acc<asmString,
2200                                   !cast<RegisterClass>(RCout#"128B"),
2201                                   !cast<RegisterClass>(RCin#"128B")>;
2202}
2203
2204multiclass T_HVX_vlutb_acc_V <string asmString> :
2205  T_HVX_vlutb_acc <asmString, VectorRegs, VectorRegs>;
2206
2207multiclass T_HVX_vlutb_acc_W <string asmString> :
2208  T_HVX_vlutb_acc <asmString, VecDblRegs, VectorRegs>;
2209
2210
2211let Itinerary = CVI_VP_LONG, Type = TypeCVI_VP, hasNewValue = 1 in
2212defm V6_vlutvvb:
2213     T_HVX_vlutb_V <"$dst.b = vlut32($src1.b,$src2.b,$src3)">, V6_vlutvvb_enc;
2214
2215let Itinerary = CVI_VP_VS_LONG, Type = TypeCVI_VP_VS, hasNewValue = 1 in
2216defm V6_vlutvwh:
2217     T_HVX_vlutb_W <"$dst.h = vlut16($src1.b,$src2.h,$src3)">, V6_vlutvwh_enc;
2218
2219let hasNewValue = 1 in {
2220  defm V6_vlutvvb_oracc:
2221       T_HVX_vlutb_acc_V <"$dst.b |= vlut32($src1.b,$src2.b,$src3)">,
2222       V6_vlutvvb_oracc_enc;
2223  defm V6_vlutvwh_oracc:
2224       T_HVX_vlutb_acc_W <"$dst.h |= vlut16($src1.b,$src2.h,$src3)">,
2225       V6_vlutvwh_oracc_enc;
2226}
2227
2228// It's a fake instruction and should not be defined?
2229def S2_cabacencbin
2230  : SInst2<(outs DoubleRegs:$dst),
2231          (ins DoubleRegs:$src1, DoubleRegs:$src2, PredRegs:$src3),
2232    "$dst = encbin($src1,$src2,$src3)">, S2_cabacencbin_enc;
2233
2234// Vhist instructions
2235def V6_vhistq
2236  : CVI_HIST_Resource1 <(outs), (ins VecPredRegs:$src1),
2237    "vhist($src1)">, V6_vhistq_enc;
2238
2239def V6_vhist
2240  : CVI_HIST_Resource1 <(outs), (ins),
2241    "vhist" >, V6_vhist_enc;
2242