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