]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/Hexagon/HexagonPseudo.td
Merge libc++ trunk r300890, and update build glue.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / Hexagon / HexagonPseudo.td
1 //===--- HexagonPseudo.td -------------------------------------------------===//
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 let PrintMethod = "printGlobalOperand" in {
11   def globaladdress : Operand<i32>;
12   def globaladdressExt : Operand<i32>;
13 }
14
15 let isPseudo = 1 in {
16 let isCodeGenOnly = 0 in
17 def A2_iconst : Pseudo<(outs IntRegs:$Rd32), (ins s23_2Imm:$Ii), "${Rd32}=iconst(#${Ii})">;
18 def DUPLEX_Pseudo : InstHexagon<(outs), (ins s32_0Imm:$offset), "DUPLEX", [], "", DUPLEX, TypePSEUDO>;
19 }
20
21 let isExtendable = 1, opExtendable = 1, opExtentBits = 6,
22     isAsmParserOnly = 1 in
23 def TFRI64_V2_ext : ALU64_rr<(outs DoubleRegs:$dst),
24                              (ins s32_0Imm:$src1, s8_0Imm:$src2),
25                              "$dst=combine(#$src1,#$src2)">;
26
27 // HI/LO Instructions
28 let isReMaterializable = 1, isMoveImm = 1, hasSideEffects = 0,
29     hasNewValue = 1, opNewValue = 0 in
30 class REG_IMMED<string RegHalf, bit Rs, bits<3> MajOp, bit MinOp>
31   : InstHexagon<(outs IntRegs:$dst),
32               (ins u16_0Imm:$imm_value),
33               "$dst"#RegHalf#"=#$imm_value", [], "", ALU32_2op_tc_1_SLOT0123, TypeALU32_2op>, OpcodeHexagon {
34     bits<5> dst;
35     bits<32> imm_value;
36
37     let Inst{27} = Rs;
38     let Inst{26-24} = MajOp;
39     let Inst{21} = MinOp;
40     let Inst{20-16} = dst;
41     let Inst{23-22} = imm_value{15-14};
42     let Inst{13-0} = imm_value{13-0};
43 }
44
45 let isAsmParserOnly = 1 in {
46   def LO : REG_IMMED<".l", 0b0, 0b001, 0b1>;
47   def HI : REG_IMMED<".h", 0b0, 0b010, 0b1>;
48 }
49
50 let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in {
51   def CONST32 : CONSTLDInst<(outs IntRegs:$Rd), (ins i32imm:$v),
52                 "$Rd = CONST32(#$v)", []>;
53   def CONST64 : CONSTLDInst<(outs DoubleRegs:$Rd), (ins i64imm:$v),
54                 "$Rd = CONST64(#$v)", []>;
55 }
56
57 let hasSideEffects = 0, isReMaterializable = 1, isPseudo = 1,
58     isCodeGenOnly = 1 in
59 def PS_true : SInst<(outs PredRegs:$dst), (ins), "", []>;
60
61 let hasSideEffects = 0, isReMaterializable = 1, isPseudo = 1,
62     isCodeGenOnly = 1 in
63 def PS_false : SInst<(outs PredRegs:$dst), (ins), "", []>;
64
65 let Defs = [R29, R30], Uses = [R31, R30, R29], isPseudo = 1 in
66 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt),
67                               ".error \"should not emit\" ", []>;
68
69 let Defs = [R29, R30, R31], Uses = [R29], isPseudo = 1 in
70 def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
71                              ".error \"should not emit\" ", []>;
72
73
74 let isBranch = 1, isTerminator = 1, hasSideEffects = 0,
75     Defs = [PC, LC0], Uses = [SA0, LC0] in {
76 def ENDLOOP0 : Endloop<(outs), (ins b30_2Imm:$offset),
77                        ":endloop0",
78                        []>;
79 }
80
81 let isBranch = 1, isTerminator = 1, hasSideEffects = 0,
82     Defs = [PC, LC1], Uses = [SA1, LC1] in {
83 def ENDLOOP1 : Endloop<(outs), (ins b30_2Imm:$offset),
84                        ":endloop1",
85                        []>;
86 }
87
88 let isExtendable = 1, isExtentSigned = 1, opExtentBits = 9, opExtentAlign = 2,
89     opExtendable = 0, hasSideEffects = 0 in
90 class LOOP_iBase<string mnemonic, Operand brOp, bit mustExtend = 0>
91          : CRInst<(outs), (ins brOp:$offset, u10_0Imm:$src2),
92            #mnemonic#"($offset,#$src2)",
93            [], "" , CR_tc_3x_SLOT3> {
94     bits<9> offset;
95     bits<10> src2;
96
97     let IClass = 0b0110;
98
99     let Inst{27-22} = 0b100100;
100     let Inst{21} = !if (!eq(mnemonic, "loop0"), 0b0, 0b1);
101     let Inst{20-16} = src2{9-5};
102     let Inst{12-8} = offset{8-4};
103     let Inst{7-5} = src2{4-2};
104     let Inst{4-3} = offset{3-2};
105     let Inst{1-0} = src2{1-0};
106 }
107
108 let isExtendable = 1, isExtentSigned = 1, opExtentBits = 9, opExtentAlign = 2,
109     opExtendable = 0, hasSideEffects = 0 in
110 class LOOP_rBase<string mnemonic, Operand brOp, bit mustExtend = 0>
111          : CRInst<(outs), (ins brOp:$offset, IntRegs:$src2),
112            #mnemonic#"($offset,$src2)",
113            [], "" ,CR_tc_3x_SLOT3> {
114     bits<9> offset;
115     bits<5> src2;
116
117     let IClass = 0b0110;
118
119     let Inst{27-22} = 0b000000;
120     let Inst{21} = !if (!eq(mnemonic, "loop0"), 0b0, 0b1);
121     let Inst{20-16} = src2;
122     let Inst{12-8} = offset{8-4};
123     let Inst{4-3} = offset{3-2};
124   }
125
126 multiclass LOOP_ri<string mnemonic> {
127   let isCodeGenOnly = 1, isExtended = 1, opExtendable = 0 in {
128     def iext: LOOP_iBase<mnemonic, b30_2Imm, 1>;
129     def rext: LOOP_rBase<mnemonic, b30_2Imm, 1>;
130   }
131 }
132
133
134 let Defs = [SA0, LC0, USR] in
135 defm J2_loop0 : LOOP_ri<"loop0">;
136
137 // Interestingly only loop0's appear to set usr.lpcfg
138 let Defs = [SA1, LC1] in
139 defm J2_loop1 : LOOP_ri<"loop1">;
140
141 let isCall = 1, hasSideEffects = 1, isPredicable = 0,
142     isExtended = 0, isExtendable = 1, opExtendable = 0,
143     isExtentSigned = 1, opExtentBits = 24, opExtentAlign = 2 in
144 class T_Call<string ExtStr>
145   : JInst<(outs), (ins a30_2Imm:$dst),
146       "call " # ExtStr # "$dst", [], "", J_tc_2early_SLOT23> {
147   let BaseOpcode = "call";
148   bits<24> dst;
149
150   let IClass = 0b0101;
151   let Inst{27-25} = 0b101;
152   let Inst{24-16,13-1} = dst{23-2};
153   let Inst{0} = 0b0;
154 }
155
156 let isCodeGenOnly = 1, isCall = 1, hasSideEffects = 1, Defs = [R16],
157     isPredicable = 0 in
158 def CALLProfile :  T_Call<"">;
159
160 let isCodeGenOnly = 1, isCall = 1, hasSideEffects = 1,
161     Defs = [PC, R31, R6, R7, P0] in
162 def PS_call_stk : T_Call<"">;
163
164 let isCall = 1, hasSideEffects = 1, cofMax1 = 1 in
165 class JUMPR_MISC_CALLR<bit isPred, bit isPredNot,
166                dag InputDag = (ins IntRegs:$Rs)>
167   : JInst<(outs), InputDag,
168       !if(isPred, !if(isPredNot, "if (!$Pu) callr $Rs",
169                                  "if ($Pu) callr $Rs"),
170                                  "callr $Rs"),
171       [], "", J_tc_2early_SLOT2> {
172     bits<5> Rs;
173     bits<2> Pu;
174     let isPredicated = isPred;
175     let isPredicatedFalse = isPredNot;
176
177     let IClass = 0b0101;
178     let Inst{27-25} = 0b000;
179     let Inst{24-23} = !if (isPred, 0b10, 0b01);
180     let Inst{22} = 0;
181     let Inst{21} = isPredNot;
182     let Inst{9-8} = !if (isPred, Pu, 0b00);
183     let Inst{20-16} = Rs;
184
185   }
186
187 let isCodeGenOnly = 1 in {
188   def PS_callr_nr : JUMPR_MISC_CALLR<0, 1>; // Call, no return.
189 }
190
191 let isCall = 1, hasSideEffects = 1,
192     isExtended = 0, isExtendable = 1, opExtendable = 0, isCodeGenOnly = 1,
193     BaseOpcode = "PS_call_nr", isExtentSigned = 1, opExtentAlign = 2,
194     Itinerary = J_tc_2early_SLOT23 in
195 class Call_nr<bits<5> nbits, bit isPred, bit isFalse, dag iops>
196   : Pseudo<(outs), iops, "">, PredRel {
197     bits<2> Pu;
198     bits<17> dst;
199     let opExtentBits = nbits;
200     let isPredicable = 0;  // !if(isPred, 0, 1);
201     let isPredicated = 0;  // isPred;
202     let isPredicatedFalse = isFalse;
203 }
204
205 def PS_call_nr : Call_nr<24, 0, 0, (ins s32_0Imm:$Ii)>;
206 //def PS_call_nrt: Call_nr<17, 1, 0, (ins PredRegs:$Pu, s32_0Imm:$dst)>;
207 //def PS_call_nrf: Call_nr<17, 1, 1, (ins PredRegs:$Pu, s32_0Imm:$dst)>;
208
209 let isBranch = 1, isIndirectBranch = 1, isBarrier = 1, Defs = [PC],
210     isPredicable = 1, hasSideEffects = 0, InputType = "reg",
211     cofMax1 = 1 in
212 class T_JMPr
213   :  InstHexagon<(outs), (ins IntRegs:$dst), "jumpr $dst", [],
214                  "", J_tc_2early_SLOT2, TypeJ>, OpcodeHexagon {
215     bits<5> dst;
216
217     let IClass = 0b0101;
218     let Inst{27-21} = 0b0010100;
219     let Inst{20-16} = dst;
220 }
221
222 // A return through builtin_eh_return.
223 let isReturn = 1, isTerminator = 1, isBarrier = 1, hasSideEffects = 0,
224     isCodeGenOnly = 1, Defs = [PC], Uses = [R28], isPredicable = 0 in
225 def EH_RETURN_JMPR : T_JMPr;
226
227 // Indirect tail-call.
228 let isPseudo = 1, isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0,
229     isTerminator = 1, isCodeGenOnly = 1 in
230 def PS_tailcall_r : T_JMPr;
231
232 //
233 // Direct tail-calls.
234 let isPseudo = 1, isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0,
235     isTerminator = 1, isCodeGenOnly = 1 in
236 def PS_tailcall_i : Pseudo<(outs), (ins a30_2Imm:$dst), "", []>;
237
238 let isCodeGenOnly = 1, isPseudo = 1, Uses = [R30], hasSideEffects = 0 in
239 def PS_aligna : Pseudo<(outs IntRegs:$Rd), (ins u32_0Imm:$A), "", []>;
240
241 // Generate frameindex addresses. The main reason for the offset operand is
242 // that every instruction that is allowed to have frame index as an operand
243 // will then have that operand followed by an immediate operand (the offset).
244 // This simplifies the frame-index elimination code.
245 //
246 let isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1,
247     isPseudo = 1, isCodeGenOnly = 1, hasSideEffects = 0 in {
248   def PS_fi  : Pseudo<(outs IntRegs:$Rd),
249                          (ins IntRegs:$fi, s32_0Imm:$off), "">;
250   def PS_fia : Pseudo<(outs IntRegs:$Rd),
251                          (ins IntRegs:$Rs, IntRegs:$fi, s32_0Imm:$off), "">;
252 }
253
254 class CondStr<string CReg, bit True, bit New> {
255   string S = "if (" # !if(True,"","!") # CReg # !if(New,".new","") # ") ";
256 }
257 class JumpOpcStr<string Mnemonic, bit New, bit Taken> {
258   string S = Mnemonic # !if(Taken, ":t", ":nt");
259 }
260 let isBranch = 1, isIndirectBranch = 1, Defs = [PC], isPredicated = 1,
261     hasSideEffects = 0, InputType = "reg", cofMax1 = 1 in
262 class T_JMPr_c <bit PredNot, bit isPredNew, bit isTak>
263   :  InstHexagon<(outs), (ins PredRegs:$src, IntRegs:$dst),
264                  CondStr<"$src", !if(PredNot,0,1), isPredNew>.S #
265                  JumpOpcStr<"jumpr", isPredNew, isTak>.S # " $dst",
266                  [], "", J_tc_2early_SLOT2, TypeJ>, OpcodeHexagon {
267
268     let isTaken = isTak;
269     let isPredicatedFalse = PredNot;
270     let isPredicatedNew = isPredNew;
271     bits<2> src;
272     bits<5> dst;
273
274     let IClass = 0b0101;
275
276     let Inst{27-22} = 0b001101;
277     let Inst{21} = PredNot;
278     let Inst{20-16} = dst;
279     let Inst{12} = isTak;
280     let Inst{11} = isPredNew;
281     let Inst{9-8} = src;
282 }
283 multiclass JMPR_Pred<bit PredNot> {
284   def NAME        : T_JMPr_c<PredNot, 0, 0>; // not taken
285   // Predicate new
286   def NAME#newpt  : T_JMPr_c<PredNot, 1, 1>; // taken
287   def NAME#new    : T_JMPr_c<PredNot, 1, 0>; // not taken
288 }
289 multiclass JMPR_base<string BaseOp> {
290   let BaseOpcode = BaseOp in {
291     def NAME : T_JMPr;
292     defm t : JMPR_Pred<0>;
293     defm f : JMPR_Pred<1>;
294   }
295 }
296 let isTerminator = 1, hasSideEffects = 0, isReturn = 1, isCodeGenOnly = 1, isBarrier = 1 in
297 defm PS_jmpret : JMPR_base<"JMPret">, PredNewRel;
298
299 //defm V6_vtran2x2_map : HexagonMapping<(outs VectorRegs:$Vy32, VectorRegs:$Vx32), (ins VectorRegs:$Vx32in, IntRegs:$Rt32), "vtrans2x2(${Vy32},${Vx32},${Rt32})", (V6_vshuff VectorRegs:$Vy32, VectorRegs:$Vx32, VectorRegs:$Vx32in, IntRegs:$Rt32)>;
300
301 // The reason for the custom inserter is to record all ALLOCA instructions
302 // in MachineFunctionInfo.
303 let Defs = [R29], isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 1 in
304 def PS_alloca: InstHexagon<(outs IntRegs:$Rd),
305       (ins IntRegs:$Rs, u32_0Imm:$A), "",
306       [], "", ALU32_2op_tc_1_SLOT0123, TypeALU32_2op>;
307
308 // Load predicate.
309 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13,
310     isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in
311 def LDriw_pred : LDInst<(outs PredRegs:$dst),
312                         (ins IntRegs:$addr, s32_0Imm:$off),
313                         ".error \"should not emit\"", []>;
314
315 // Load modifier.
316 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13,
317     isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in
318 def LDriw_mod : LDInst<(outs ModRegs:$dst),
319                         (ins IntRegs:$addr, s32_0Imm:$off),
320                         ".error \"should not emit\"", []>;
321
322 // Vector load
323 let Predicates = [HasV60T, UseHVX] in
324 let mayLoad = 1, validSubTargets = HasV60SubT, hasSideEffects = 0 in
325   class V6_LDInst<dag outs, dag ins, string asmstr, list<dag> pattern = [],
326                   string cstr = "", InstrItinClass itin = CVI_VM_LD,
327                   IType type = TypeCVI_VM_LD>
328   : InstHexagon<outs, ins, asmstr, pattern, cstr, itin, type>;
329
330 // Vector store
331 let Predicates = [HasV60T, UseHVX] in
332 let mayStore = 1, validSubTargets = HasV60SubT, hasSideEffects = 0 in
333 class V6_STInst<dag outs, dag ins, string asmstr, list<dag> pattern = [],
334                 string cstr = "", InstrItinClass itin = CVI_VM_ST,
335                 IType type = TypeCVI_VM_ST>
336 : InstHexagon<outs, ins, asmstr, pattern, cstr, itin, type>;
337
338 let isCodeGenOnly = 1, isPseudo = 1 in
339 def PS_pselect : ALU64_rr<(outs DoubleRegs:$Rd),
340       (ins PredRegs:$Pu, DoubleRegs:$Rs, DoubleRegs:$Rt),
341       ".error \"should not emit\" ", []>;
342
343 let isBranch = 1, isBarrier = 1, Defs = [PC], hasSideEffects = 0,
344     isPredicable = 1,
345     isExtendable = 1, opExtendable = 0, isExtentSigned = 1,
346     opExtentBits = 24, opExtentAlign = 2, InputType = "imm" in
347 class T_JMP<string ExtStr>
348   : JInst_CJUMP_UCJUMP<(outs), (ins b30_2Imm:$dst),
349       "jump " # ExtStr # "$dst",
350       [], "", J_tc_2early_CJUMP_UCJUMP_ARCHDEPSLOT> {
351     bits<24> dst;
352     let IClass = 0b0101;
353
354     let Inst{27-25} = 0b100;
355     let Inst{24-16} = dst{23-15};
356     let Inst{13-1} = dst{14-2};
357 }
358
359 // Restore registers and dealloc return function call.
360 let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
361     Defs = [R29, R30, R31, PC], isPredicable = 0, isAsmParserOnly = 1 in {
362   def RESTORE_DEALLOC_RET_JMP_V4 : T_JMP<"">;
363
364   let isExtended = 1, opExtendable = 0 in
365   def RESTORE_DEALLOC_RET_JMP_V4_EXT : T_JMP<"">;
366
367   let Defs = [R14, R15, R28, R29, R30, R31, PC] in {
368     def RESTORE_DEALLOC_RET_JMP_V4_PIC : T_JMP<"">;
369
370     let isExtended = 1, opExtendable = 0 in
371     def RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC : T_JMP<"">;
372   }
373 }
374
375 // Restore registers and dealloc frame before a tail call.
376 let isCall = 1, Defs = [R29, R30, R31, PC], isAsmParserOnly = 1 in {
377   def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : T_Call<"">, PredRel;
378
379   let isExtended = 1, opExtendable = 0 in
380   def RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT : T_Call<"">, PredRel;
381
382   let Defs = [R14, R15, R28, R29, R30, R31, PC] in {
383     def RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC : T_Call<"">, PredRel;
384
385     let isExtended = 1, opExtendable = 0 in
386     def RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC : T_Call<"">, PredRel;
387   }
388 }
389
390 // Save registers function call.
391 let isCall = 1, Uses = [R29, R31], isAsmParserOnly = 1 in {
392   def SAVE_REGISTERS_CALL_V4 : T_Call<"">, PredRel;
393
394   let isExtended = 1, opExtendable = 0 in
395   def SAVE_REGISTERS_CALL_V4_EXT : T_Call<"">, PredRel;
396
397   let Defs = [P0] in
398   def SAVE_REGISTERS_CALL_V4STK : T_Call<"">, PredRel;
399
400   let Defs = [P0], isExtended = 1, opExtendable = 0 in
401   def SAVE_REGISTERS_CALL_V4STK_EXT : T_Call<"">, PredRel;
402
403   let Defs = [R14, R15, R28] in
404   def SAVE_REGISTERS_CALL_V4_PIC : T_Call<"">, PredRel;
405
406   let Defs = [R14, R15, R28], isExtended = 1, opExtendable = 0 in
407   def SAVE_REGISTERS_CALL_V4_EXT_PIC : T_Call<"">, PredRel;
408
409   let Defs = [R14, R15, R28, P0] in
410   def SAVE_REGISTERS_CALL_V4STK_PIC : T_Call<"">, PredRel;
411
412   let Defs = [R14, R15, R28, P0], isExtended = 1, opExtendable = 0 in
413   def SAVE_REGISTERS_CALL_V4STK_EXT_PIC : T_Call<"">, PredRel;
414 }
415
416 // Vector load/store pseudos
417
418 let isPseudo = 1, isCodeGenOnly = 1, validSubTargets = HasV60SubT in
419 class STrivv_template<RegisterClass RC>
420   : V6_STInst<(outs), (ins IntRegs:$addr, s32_0Imm:$off, RC:$src), "", []>;
421
422 def PS_vstorerw_ai: STrivv_template<VecDblRegs>,
423       Requires<[HasV60T,UseHVXSgl]>;
424 def PS_vstorerwu_ai: STrivv_template<VecDblRegs>,
425       Requires<[HasV60T,UseHVXSgl]>;
426 def PS_vstorerw_ai_128B: STrivv_template<VecDblRegs128B>,
427       Requires<[HasV60T,UseHVXDbl]>;
428 def PS_vstorerwu_ai_128B: STrivv_template<VecDblRegs128B>,
429       Requires<[HasV60T,UseHVXDbl]>;
430
431
432 let isPseudo = 1, isCodeGenOnly = 1, validSubTargets = HasV60SubT in
433 class LDrivv_template<RegisterClass RC>
434   : V6_LDInst<(outs RC:$dst), (ins IntRegs:$addr, s32_0Imm:$off), "", []>;
435
436 def PS_vloadrw_ai: LDrivv_template<VecDblRegs>,
437       Requires<[HasV60T,UseHVXSgl]>;
438 def PS_vloadrwu_ai: LDrivv_template<VecDblRegs>,
439       Requires<[HasV60T,UseHVXSgl]>;
440 def PS_vloadrw_ai_128B: LDrivv_template<VecDblRegs128B>,
441       Requires<[HasV60T,UseHVXDbl]>;
442 def PS_vloadrwu_ai_128B: LDrivv_template<VecDblRegs128B>,
443       Requires<[HasV60T,UseHVXDbl]>;
444
445 // Store vector predicate pseudo.
446 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 13,
447     isCodeGenOnly = 1, isPseudo = 1, mayStore = 1, hasSideEffects = 0 in {
448   def PS_vstorerq_ai : STInst<(outs),
449               (ins IntRegs:$base, s32_0Imm:$offset, VecPredRegs:$src1),
450               ".error \"should not emit\" ", []>,
451               Requires<[HasV60T,UseHVXSgl]>;
452
453   def PS_vstorerq_ai_128B : STInst<(outs),
454               (ins IntRegs:$base, s32_0Imm:$offset, VectorRegs:$src1),
455               ".error \"should not emit\" ", []>,
456             Requires<[HasV60T,UseHVXSgl]>;
457
458   def PS_vloadrq_ai : STInst<(outs),
459               (ins IntRegs:$base, s32_0Imm:$offset, VecPredRegs128B:$src1),
460               ".error \"should not emit\" ", []>,
461             Requires<[HasV60T,UseHVXDbl]>;
462
463   def PS_vloadrq_ai_128B : STInst<(outs),
464               (ins IntRegs:$base, s32_0Imm:$offset, VecPredRegs128B:$src1),
465               ".error \"should not emit\" ", []>,
466             Requires<[HasV60T,UseHVXDbl]>;
467 }
468
469 class VSELInst<dag outs, dag ins, string asmstr, list<dag> pattern = [],
470               string cstr = "", InstrItinClass itin = CVI_VA_DV,
471               IType type = TypeCVI_VA_DV>
472   : InstHexagon<outs, ins, asmstr, pattern, cstr, itin, type>;
473
474 let isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in {
475   def PS_vselect: VSELInst<(outs VectorRegs:$dst),
476         (ins PredRegs:$src1, VectorRegs:$src2, VectorRegs:$src3), "", []>,
477         Requires<[HasV60T,UseHVXSgl]>;
478   def PS_vselect_128B: VSELInst<(outs VectorRegs128B:$dst),
479         (ins PredRegs:$src1, VectorRegs128B:$src2, VectorRegs128B:$src3),
480         "", []>, Requires<[HasV60T,UseHVXDbl]>;
481   def PS_wselect: VSELInst<(outs VecDblRegs:$dst),
482         (ins PredRegs:$src1, VecDblRegs:$src2, VecDblRegs:$src3), "", []>,
483         Requires<[HasV60T,UseHVXSgl]>;
484   def PS_wselect_128B: VSELInst<(outs VecDblRegs128B:$dst),
485         (ins PredRegs:$src1, VecDblRegs128B:$src2, VecDblRegs128B:$src3),
486         "", []>, Requires<[HasV60T,UseHVXDbl]>;
487 }
488
489 // Store predicate.
490 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 13,
491     isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in
492 def STriw_pred : STInst<(outs),
493       (ins IntRegs:$addr, s32_0Imm:$off, PredRegs:$src1),
494       ".error \"should not emit\"", []>;
495 // Store modifier.
496 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 13,
497     isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in
498 def STriw_mod : STInst<(outs),
499       (ins IntRegs:$addr, s32_0Imm:$off, ModRegs:$src1),
500       ".error \"should not emit\"", []>;
501
502 let isExtendable = 1, opExtendable = 1, opExtentBits = 6,
503     isAsmParserOnly = 1 in
504 def TFRI64_V4 : ALU64_rr<(outs DoubleRegs:$dst), (ins u64_0Imm:$src1),
505                          "$dst = #$src1">;
506
507 // Hexagon doesn't have a vector multiply with C semantics.
508 // Instead, generate a pseudo instruction that gets expaneded into two
509 // scalar MPYI instructions.
510 // This is expanded by ExpandPostRAPseudos.
511 let isPseudo = 1 in
512 def PS_vmulw : PseudoM<(outs DoubleRegs:$Rd),
513       (ins DoubleRegs:$Rs, DoubleRegs:$Rt), "", []>;
514
515 let isPseudo = 1 in
516 def PS_vmulw_acc : PseudoM<(outs DoubleRegs:$Rd),
517       (ins DoubleRegs:$Rx, DoubleRegs:$Rs, DoubleRegs:$Rt), "", [],
518       "$Rd = $Rx">;
519
520 def DuplexIClass0:  InstDuplex < 0 >;
521 def DuplexIClass1:  InstDuplex < 1 >;
522 def DuplexIClass2:  InstDuplex < 2 >;
523 let isExtendable = 1 in {
524   def DuplexIClass3:  InstDuplex < 3 >;
525   def DuplexIClass4:  InstDuplex < 4 >;
526   def DuplexIClass5:  InstDuplex < 5 >;
527   def DuplexIClass6:  InstDuplex < 6 >;
528   def DuplexIClass7:  InstDuplex < 7 >;
529 }
530 def DuplexIClass8:  InstDuplex < 8 >;
531 def DuplexIClass9:  InstDuplex < 9 >;
532 def DuplexIClassA:  InstDuplex < 0xA >;
533 def DuplexIClassB:  InstDuplex < 0xB >;
534 def DuplexIClassC:  InstDuplex < 0xC >;
535 def DuplexIClassD:  InstDuplex < 0xD >;
536 def DuplexIClassE:  InstDuplex < 0xE >;
537 def DuplexIClassF:  InstDuplex < 0xF >;