OSDN Git Service

reverting patch 176508.
[android-x86/external-llvm.git] / lib / Target / Hexagon / HexagonInstrInfo.td
1 //==- HexagonInstrInfo.td - Target Description for Hexagon -*- 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 instructions in TableGen format.
11 //
12 //===----------------------------------------------------------------------===//
13
14 include "HexagonInstrFormats.td"
15 include "HexagonOperands.td"
16
17 // Multi-class for logical operators.
18 multiclass ALU32_rr_ri<string OpcStr, SDNode OpNode> {
19   def rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
20                  !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
21                  [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$b),
22                                                    (i32 IntRegs:$c)))]>;
23   def ri : ALU32_ri<(outs IntRegs:$dst), (ins s10Imm:$b, IntRegs:$c),
24                  !strconcat("$dst = ", !strconcat(OpcStr, "(#$b, $c)")),
25                  [(set (i32 IntRegs:$dst), (OpNode s10Imm:$b,
26                                                    (i32 IntRegs:$c)))]>;
27 }
28
29 // Multi-class for compare ops.
30 let isCompare = 1 in {
31 multiclass CMP64_rr<string OpcStr, PatFrag OpNode> {
32   def rr : ALU64_rr<(outs PredRegs:$dst), (ins DoubleRegs:$b, DoubleRegs:$c),
33                  !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
34                  [(set (i1 PredRegs:$dst),
35                        (OpNode (i64 DoubleRegs:$b), (i64 DoubleRegs:$c)))]>;
36 }
37 multiclass CMP32_rr<string OpcStr, PatFrag OpNode> {
38   def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
39                  !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
40                  [(set (i1 PredRegs:$dst),
41                        (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>;
42 }
43
44 multiclass CMP32_rr_ri_s10<string OpcStr, string CextOp, PatFrag OpNode> {
45   let CextOpcode = CextOp in {
46     let InputType = "reg" in
47     def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
48                    !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
49                    [(set (i1 PredRegs:$dst),
50                          (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>;
51
52     let isExtendable = 1, opExtendable = 2, isExtentSigned = 1,
53     opExtentBits = 10, InputType = "imm" in
54     def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s10Ext:$c),
55                    !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
56                    [(set (i1 PredRegs:$dst),
57                          (OpNode (i32 IntRegs:$b), s10ExtPred:$c))]>;
58   }
59 }
60
61 multiclass CMP32_rr_ri_u9<string OpcStr, string CextOp, PatFrag OpNode> {
62   let CextOpcode = CextOp in {
63     let InputType = "reg" in
64     def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
65                    !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
66                    [(set (i1 PredRegs:$dst),
67                          (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>;
68
69     let isExtendable = 1, opExtendable = 2, isExtentSigned = 0,
70     opExtentBits = 9, InputType = "imm" in
71     def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u9Ext:$c),
72                    !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
73                    [(set (i1 PredRegs:$dst),
74                          (OpNode (i32 IntRegs:$b), u9ExtPred:$c))]>;
75   }
76 }
77
78 multiclass CMP32_ri_u8<string OpcStr, PatFrag OpNode> {
79 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 8 in
80   def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u8Ext:$c),
81                  !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
82                  [(set (i1 PredRegs:$dst), (OpNode (i32 IntRegs:$b),
83                                                    u8ExtPred:$c))]>;
84 }
85
86 multiclass CMP32_ri_s8<string OpcStr, PatFrag OpNode> {
87 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in
88   def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s8Ext:$c),
89                  !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
90                  [(set (i1 PredRegs:$dst), (OpNode (i32 IntRegs:$b),
91                                                    s8ExtPred:$c))]>;
92 }
93 }
94
95 //===----------------------------------------------------------------------===//
96 // ALU32/ALU (Instructions with register-register form)
97 //===----------------------------------------------------------------------===//
98 multiclass ALU32_Pbase<string mnemonic, bit isNot,
99                        bit isPredNew> {
100
101   let PNewValue = !if(isPredNew, "new", "") in
102   def NAME : ALU32_rr<(outs IntRegs:$dst),
103             (ins PredRegs:$src1, IntRegs:$src2, IntRegs: $src3),
104             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ",
105             ") $dst = ")#mnemonic#"($src2, $src3)",
106             []>;
107 }
108
109 multiclass ALU32_Pred<string mnemonic, bit PredNot> {
110   let PredSense = !if(PredNot, "false", "true") in {
111     defm _c#NAME : ALU32_Pbase<mnemonic, PredNot, 0>;
112     // Predicate new
113     defm _cdn#NAME : ALU32_Pbase<mnemonic, PredNot, 1>;
114   }
115 }
116
117 let InputType = "reg" in
118 multiclass ALU32_base<string mnemonic, string CextOp, SDNode OpNode> {
119   let CextOpcode = CextOp, BaseOpcode = CextOp#_rr in {
120     let isPredicable = 1 in
121     def NAME : ALU32_rr<(outs IntRegs:$dst),
122             (ins IntRegs:$src1, IntRegs:$src2),
123             "$dst = "#mnemonic#"($src1, $src2)",
124             [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$src1),
125                                               (i32 IntRegs:$src2)))]>;
126
127     let neverHasSideEffects = 1, isPredicated = 1 in {
128       defm Pt : ALU32_Pred<mnemonic, 0>;
129       defm NotPt : ALU32_Pred<mnemonic, 1>;
130     }
131   }
132 }
133
134 let isCommutable = 1 in {
135   defm ADD_rr : ALU32_base<"add", "ADD", add>, ImmRegRel, PredNewRel;
136   defm AND_rr : ALU32_base<"and", "AND", and>, ImmRegRel, PredNewRel;
137   defm XOR_rr : ALU32_base<"xor", "XOR", xor>, ImmRegRel, PredNewRel;
138   defm OR_rr  : ALU32_base<"or", "OR", or>, ImmRegRel, PredNewRel;
139 }
140
141 defm SUB_rr : ALU32_base<"sub", "SUB", sub>, ImmRegRel, PredNewRel;
142
143 //===----------------------------------------------------------------------===//
144 // ALU32/ALU (ADD with register-immediate form)
145 //===----------------------------------------------------------------------===//
146 multiclass ALU32ri_Pbase<string mnemonic, bit isNot, bit isPredNew> {
147   let PNewValue = !if(isPredNew, "new", "") in
148   def NAME : ALU32_ri<(outs IntRegs:$dst),
149             (ins PredRegs:$src1, IntRegs:$src2, s8Ext: $src3),
150             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ",
151             ") $dst = ")#mnemonic#"($src2, #$src3)",
152             []>;
153 }
154
155 multiclass ALU32ri_Pred<string mnemonic, bit PredNot> {
156   let PredSense = !if(PredNot, "false", "true") in {
157     defm _c#NAME : ALU32ri_Pbase<mnemonic, PredNot, 0>;
158     // Predicate new
159     defm _cdn#NAME : ALU32ri_Pbase<mnemonic, PredNot, 1>;
160   }
161 }
162
163 let isExtendable = 1, InputType = "imm" in
164 multiclass ALU32ri_base<string mnemonic, string CextOp, SDNode OpNode> {
165   let CextOpcode = CextOp, BaseOpcode = CextOp#_ri in {
166     let opExtendable = 2, isExtentSigned = 1, opExtentBits = 16,
167     isPredicable = 1 in
168     def NAME : ALU32_ri<(outs IntRegs:$dst),
169             (ins IntRegs:$src1, s16Ext:$src2),
170             "$dst = "#mnemonic#"($src1, #$src2)",
171             [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$src1),
172                                               (s16ExtPred:$src2)))]>;
173
174     let opExtendable = 3, isExtentSigned = 1, opExtentBits = 8,
175     neverHasSideEffects = 1, isPredicated = 1 in {
176       defm Pt : ALU32ri_Pred<mnemonic, 0>;
177       defm NotPt : ALU32ri_Pred<mnemonic, 1>;
178     }
179   }
180 }
181
182 defm ADD_ri : ALU32ri_base<"add", "ADD", add>, ImmRegRel, PredNewRel;
183
184 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 10,
185 CextOpcode = "OR", InputType = "imm" in
186 def OR_ri : ALU32_ri<(outs IntRegs:$dst),
187             (ins IntRegs:$src1, s10Ext:$src2),
188             "$dst = or($src1, #$src2)",
189             [(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1),
190                                           s10ExtPred:$src2))]>, ImmRegRel;
191
192 def NOT_rr : ALU32_rr<(outs IntRegs:$dst),
193             (ins IntRegs:$src1),
194             "$dst = not($src1)",
195             [(set (i32 IntRegs:$dst), (not (i32 IntRegs:$src1)))]>;
196
197 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 10,
198 InputType = "imm", CextOpcode = "AND" in
199 def AND_ri : ALU32_ri<(outs IntRegs:$dst),
200             (ins IntRegs:$src1, s10Ext:$src2),
201             "$dst = and($src1, #$src2)",
202             [(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1),
203                                            s10ExtPred:$src2))]>, ImmRegRel;
204 // Negate.
205 def NEG : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
206           "$dst = neg($src1)",
207           [(set (i32 IntRegs:$dst), (ineg (i32 IntRegs:$src1)))]>;
208 // Nop.
209 let neverHasSideEffects = 1 in
210 def NOP : ALU32_rr<(outs), (ins),
211           "nop",
212           []>;
213
214 // Rd32=sub(#s10,Rs32)
215 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 10,
216 CextOpcode = "SUB", InputType = "imm" in
217 def SUB_ri : ALU32_ri<(outs IntRegs:$dst),
218             (ins s10Ext:$src1, IntRegs:$src2),
219             "$dst = sub(#$src1, $src2)",
220             [(set IntRegs:$dst, (sub s10ExtPred:$src1, IntRegs:$src2))]>,
221             ImmRegRel;
222
223
224 multiclass TFR_Pred<bit PredNot> {
225   let PredSense = !if(PredNot, "false", "true") in {
226     def _c#NAME : ALU32_rr<(outs IntRegs:$dst),
227                            (ins PredRegs:$src1, IntRegs:$src2),
228             !if(PredNot, "if (!$src1", "if ($src1")#") $dst = $src2",
229             []>;
230     // Predicate new
231     let PNewValue = "new" in
232     def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst),
233                              (ins PredRegs:$src1, IntRegs:$src2),
234             !if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = $src2",
235             []>;
236   }
237 }
238
239 let InputType = "reg", neverHasSideEffects = 1 in
240 multiclass TFR_base<string CextOp> {
241   let CextOpcode = CextOp, BaseOpcode = CextOp in {
242     let isPredicable = 1 in
243     def NAME : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
244             "$dst = $src1",
245             []>;
246
247     let  isPredicated = 1 in {
248       defm Pt : TFR_Pred<0>;
249       defm NotPt : TFR_Pred<1>;
250     }
251   }
252 }
253
254 class T_TFR64_Pred<bit PredNot, bit isPredNew>
255             : ALU32_rr<(outs DoubleRegs:$dst),
256                        (ins PredRegs:$src1, DoubleRegs:$src2),
257             !if(PredNot, "if (!$src1", "if ($src1")#
258             !if(isPredNew, ".new) ", ") ")#"$dst = $src2", []>
259 {
260     bits<5> dst;
261     bits<2> src1;
262     bits<5> src2;
263
264     let IClass = 0b1111;
265     let Inst{27-24} = 0b1101;
266     let Inst{13} = isPredNew;
267     let Inst{7} = PredNot;
268     let Inst{4-0} = dst;
269     let Inst{6-5} = src1;
270     let Inst{20-17} = src2{4-1};
271     let Inst{16} = 0b1;
272     let Inst{12-9} = src2{4-1};
273     let Inst{8} = 0b0;
274 }
275
276 multiclass TFR64_Pred<bit PredNot> {
277   let PredSense = !if(PredNot, "false", "true") in {
278     def _c#NAME : T_TFR64_Pred<PredNot, 0>;
279
280     let PNewValue = "new" in
281     def _cdn#NAME : T_TFR64_Pred<PredNot, 1>; // Predicate new
282   }
283 }
284
285 let neverHasSideEffects = 1 in
286 multiclass TFR64_base<string BaseName> {
287   let BaseOpcode = BaseName in {
288     let isPredicable = 1 in
289     def NAME : ALU32Inst <(outs DoubleRegs:$dst),
290                           (ins DoubleRegs:$src1),
291                           "$dst = $src1" > {
292         bits<5> dst;
293         bits<5> src1;
294
295         let IClass = 0b1111;
296         let Inst{27-23} = 0b01010;
297         let Inst{4-0} = dst;
298         let Inst{20-17} = src1{4-1};
299         let Inst{16} = 0b1;
300         let Inst{12-9} = src1{4-1};
301         let Inst{8} = 0b0;
302     }
303
304     let  isPredicated = 1 in {
305       defm Pt : TFR64_Pred<0>;
306       defm NotPt : TFR64_Pred<1>;
307     }
308   }
309 }
310
311 multiclass TFRI_Pred<bit PredNot> {
312   let isMoveImm = 1, PredSense = !if(PredNot, "false", "true") in {
313     def _c#NAME : ALU32_ri<(outs IntRegs:$dst),
314                            (ins PredRegs:$src1, s12Ext:$src2),
315             !if(PredNot, "if (!$src1", "if ($src1")#") $dst = #$src2",
316             []>;
317
318     // Predicate new
319     let PNewValue = "new" in
320     def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst),
321                              (ins PredRegs:$src1, s12Ext:$src2),
322             !if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = #$src2",
323             []>;
324   }
325 }
326
327 let InputType = "imm", isExtendable = 1, isExtentSigned = 1 in
328 multiclass TFRI_base<string CextOp> {
329   let CextOpcode = CextOp, BaseOpcode = CextOp#I in {
330     let isAsCheapAsAMove = 1 , opExtendable = 1, opExtentBits = 16,
331     isMoveImm = 1, isPredicable = 1, isReMaterializable = 1 in
332     def NAME : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1),
333             "$dst = #$src1",
334             [(set (i32 IntRegs:$dst), s16ExtPred:$src1)]>;
335
336     let opExtendable = 2,  opExtentBits = 12, neverHasSideEffects = 1,
337     isPredicated = 1 in {
338       defm Pt    : TFRI_Pred<0>;
339       defm NotPt : TFRI_Pred<1>;
340     }
341   }
342 }
343
344 defm TFRI : TFRI_base<"TFR">, ImmRegRel, PredNewRel;
345 defm TFR : TFR_base<"TFR">, ImmRegRel, PredNewRel;
346 defm TFR64 : TFR64_base<"TFR64">, PredNewRel;
347
348 // Transfer control register.
349 let neverHasSideEffects = 1 in
350 def TFCR : CRInst<(outs CRRegs:$dst), (ins IntRegs:$src1),
351            "$dst = $src1",
352            []>;
353 //===----------------------------------------------------------------------===//
354 // ALU32/ALU -
355 //===----------------------------------------------------------------------===//
356
357
358 //===----------------------------------------------------------------------===//
359 // ALU32/PERM +
360 //===----------------------------------------------------------------------===//
361
362 // Combine.
363
364 def SDTHexagonI64I32I32 : SDTypeProfile<1, 2,
365   [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
366
367 def HexagonWrapperCombineII :
368   SDNode<"HexagonISD::WrapperCombineII", SDTHexagonI64I32I32>;
369 def HexagonWrapperCombineRR :
370   SDNode<"HexagonISD::WrapperCombineRR", SDTHexagonI64I32I32>;
371
372 // Combines the two integer registers SRC1 and SRC2 into a double register.
373 let isPredicable = 1 in
374 def COMBINE_rr : ALU32_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src1,
375                                                        IntRegs:$src2),
376   "$dst = combine($src1, $src2)",
377   [(set (i64 DoubleRegs:$dst),
378         (i64 (HexagonWrapperCombineRR (i32 IntRegs:$src1),
379                                       (i32 IntRegs:$src2))))]>;
380
381 // Rd=combine(Rt.[HL], Rs.[HL])
382 class COMBINE_halves<string A, string B>: ALU32_rr<(outs IntRegs:$dst),
383                                                    (ins IntRegs:$src1,
384                                                         IntRegs:$src2),
385   "$dst = combine($src1."# A #", $src2."# B #")", []>;
386
387 let isPredicable = 1 in {
388   def COMBINE_hh : COMBINE_halves<"H", "H">;
389   def COMBINE_hl : COMBINE_halves<"H", "L">;
390   def COMBINE_lh : COMBINE_halves<"L", "H">;
391   def COMBINE_ll : COMBINE_halves<"L", "L">;
392 }
393
394 def : Pat<(i32 (trunc (i64 (srl (i64 DoubleRegs:$a), (i32 16))))),
395   (COMBINE_lh (EXTRACT_SUBREG (i64 DoubleRegs:$a), subreg_hireg),
396               (EXTRACT_SUBREG (i64 DoubleRegs:$a), subreg_loreg))>;
397
398 // Combines the two immediates SRC1 and SRC2 into a double register.
399 class COMBINE_imm<Operand imm1, Operand imm2, PatLeaf pat1, PatLeaf pat2> :
400   ALU32_ii<(outs DoubleRegs:$dst), (ins imm1:$src1, imm2:$src2),
401   "$dst = combine(#$src1, #$src2)",
402   [(set (i64 DoubleRegs:$dst),
403         (i64 (HexagonWrapperCombineII (i32 pat1:$src1), (i32 pat2:$src2))))]>;
404
405 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 8 in
406 def COMBINE_Ii : COMBINE_imm<s8Ext, s8Imm, s8ExtPred, s8ImmPred>;
407
408 // Mux.
409 def VMUX_prr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1,
410                                                    DoubleRegs:$src2,
411                                                    DoubleRegs:$src3),
412             "$dst = vmux($src1, $src2, $src3)",
413             []>;
414
415 let CextOpcode = "MUX", InputType = "reg" in
416 def MUX_rr : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1,
417                                             IntRegs:$src2, IntRegs:$src3),
418              "$dst = mux($src1, $src2, $src3)",
419              [(set (i32 IntRegs:$dst),
420                    (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2),
421                                 (i32 IntRegs:$src3))))]>, ImmRegRel;
422
423 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
424 CextOpcode = "MUX", InputType = "imm" in
425 def MUX_ir : ALU32_ir<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Ext:$src2,
426                                                 IntRegs:$src3),
427              "$dst = mux($src1, #$src2, $src3)",
428              [(set (i32 IntRegs:$dst),
429                    (i32 (select (i1 PredRegs:$src1), s8ExtPred:$src2,
430                                 (i32 IntRegs:$src3))))]>, ImmRegRel;
431
432 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 8,
433 CextOpcode = "MUX", InputType = "imm" in
434 def MUX_ri : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2,
435                                                 s8Ext:$src3),
436              "$dst = mux($src1, $src2, #$src3)",
437              [(set (i32 IntRegs:$dst),
438                    (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2),
439                                  s8ExtPred:$src3)))]>, ImmRegRel;
440
441 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in
442 def MUX_ii : ALU32_ii<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Ext:$src2,
443                                                 s8Imm:$src3),
444              "$dst = mux($src1, #$src2, #$src3)",
445              [(set (i32 IntRegs:$dst), (i32 (select (i1 PredRegs:$src1),
446                                                     s8ExtPred:$src2,
447                                                     s8ImmPred:$src3)))]>;
448
449 // Shift halfword.
450 let isPredicable = 1 in
451 def ASLH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
452            "$dst = aslh($src1)",
453            [(set (i32 IntRegs:$dst), (shl 16, (i32 IntRegs:$src1)))]>;
454
455 let isPredicable = 1 in
456 def ASRH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
457            "$dst = asrh($src1)",
458            [(set (i32 IntRegs:$dst), (sra 16, (i32 IntRegs:$src1)))]>;
459
460 // Sign extend.
461 let isPredicable = 1 in
462 def SXTB : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
463            "$dst = sxtb($src1)",
464            [(set (i32 IntRegs:$dst), (sext_inreg (i32 IntRegs:$src1), i8))]>;
465
466 let isPredicable = 1 in
467 def SXTH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
468            "$dst = sxth($src1)",
469            [(set (i32 IntRegs:$dst), (sext_inreg (i32 IntRegs:$src1), i16))]>;
470
471 // Zero extend.
472 let isPredicable = 1, neverHasSideEffects = 1 in
473 def ZXTB : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
474            "$dst = zxtb($src1)",
475            []>;
476
477 let isPredicable = 1, neverHasSideEffects = 1 in
478 def ZXTH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
479                     "$dst = zxth($src1)",
480                     []>;
481 //===----------------------------------------------------------------------===//
482 // ALU32/PERM -
483 //===----------------------------------------------------------------------===//
484
485
486 //===----------------------------------------------------------------------===//
487 // ALU32/PRED +
488 //===----------------------------------------------------------------------===//
489
490 // Conditional combine.
491 let neverHasSideEffects = 1, isPredicated = 1 in
492 def COMBINE_rr_cPt : ALU32_rr<(outs DoubleRegs:$dst),
493             (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
494             "if ($src1) $dst = combine($src2, $src3)",
495             []>;
496
497 let neverHasSideEffects = 1, isPredicated = 1 in
498 def COMBINE_rr_cNotPt : ALU32_rr<(outs DoubleRegs:$dst),
499             (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
500             "if (!$src1) $dst = combine($src2, $src3)",
501             []>;
502
503 let neverHasSideEffects = 1, isPredicated = 1 in
504 def COMBINE_rr_cdnPt : ALU32_rr<(outs DoubleRegs:$dst),
505             (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
506             "if ($src1.new) $dst = combine($src2, $src3)",
507             []>;
508
509 let neverHasSideEffects = 1, isPredicated = 1 in
510 def COMBINE_rr_cdnNotPt : ALU32_rr<(outs DoubleRegs:$dst),
511             (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
512             "if (!$src1.new) $dst = combine($src2, $src3)",
513             []>;
514
515 // Compare.
516 defm CMPGTU : CMP32_rr_ri_u9<"cmp.gtu", "CMPGTU", setugt>, ImmRegRel;
517 defm CMPGT : CMP32_rr_ri_s10<"cmp.gt", "CMPGT", setgt>, ImmRegRel;
518 defm CMPLT : CMP32_rr<"cmp.lt", setlt>;
519 defm CMPLTU : CMP32_rr<"cmp.ltu", setult>;
520 defm CMPEQ : CMP32_rr_ri_s10<"cmp.eq", "CMPEQ", seteq>, ImmRegRel;
521 defm CMPGE : CMP32_ri_s8<"cmp.ge", setge>;
522 defm CMPGEU : CMP32_ri_u8<"cmp.geu", setuge>;
523
524 def CTLZ_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1),
525     "$dst = cl0($src1)",
526     [(set (i32 IntRegs:$dst), (ctlz (i32 IntRegs:$src1)))]>;
527
528 def CTTZ_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1),
529     "$dst = ct0($src1)",
530     [(set (i32 IntRegs:$dst), (cttz (i32 IntRegs:$src1)))]>;
531
532 def CTLZ64_rr : SInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1),
533     "$dst = cl0($src1)",
534     [(set (i32 IntRegs:$dst), (i32 (trunc (ctlz (i64 DoubleRegs:$src1)))))]>;
535
536 def CTTZ64_rr : SInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1),
537     "$dst = ct0($src1)",
538     [(set (i32 IntRegs:$dst), (i32 (trunc (cttz (i64 DoubleRegs:$src1)))))]>;
539
540 def TSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
541     "$dst = tstbit($src1, $src2)",
542     [(set (i1 PredRegs:$dst),
543           (setne (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>;
544
545 def TSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
546     "$dst = tstbit($src1, $src2)",
547     [(set (i1 PredRegs:$dst),
548           (setne (and (shl 1, (u5ImmPred:$src2)), (i32 IntRegs:$src1)), 0))]>;
549
550 //===----------------------------------------------------------------------===//
551 // ALU32/PRED -
552 //===----------------------------------------------------------------------===//
553
554
555 //===----------------------------------------------------------------------===//
556 // ALU64/ALU +
557 //===----------------------------------------------------------------------===//
558 // Add.
559 def ADD64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
560                                                      DoubleRegs:$src2),
561                "$dst = add($src1, $src2)",
562                [(set (i64 DoubleRegs:$dst), (add (i64 DoubleRegs:$src1),
563                                                  (i64 DoubleRegs:$src2)))]>;
564
565 // Add halfword.
566
567 // Compare.
568 defm CMPEHexagon4 : CMP64_rr<"cmp.eq", seteq>;
569 defm CMPGT64 : CMP64_rr<"cmp.gt", setgt>;
570 defm CMPGTU64 : CMP64_rr<"cmp.gtu", setugt>;
571
572 // Logical operations.
573 def AND_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
574                                                      DoubleRegs:$src2),
575                "$dst = and($src1, $src2)",
576                [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1),
577                                                  (i64 DoubleRegs:$src2)))]>;
578
579 def OR_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
580                                                     DoubleRegs:$src2),
581               "$dst = or($src1, $src2)",
582               [(set (i64 DoubleRegs:$dst), (or (i64 DoubleRegs:$src1),
583                                                (i64 DoubleRegs:$src2)))]>;
584
585 def XOR_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
586                                                      DoubleRegs:$src2),
587                "$dst = xor($src1, $src2)",
588                [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1),
589                                                  (i64 DoubleRegs:$src2)))]>;
590
591 // Maximum.
592 def MAXw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
593               "$dst = max($src2, $src1)",
594               [(set (i32 IntRegs:$dst),
595                     (i32 (select (i1 (setlt (i32 IntRegs:$src2),
596                                             (i32 IntRegs:$src1))),
597                                  (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>;
598
599 def MAXUw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
600               "$dst = maxu($src2, $src1)",
601               [(set (i32 IntRegs:$dst),
602                     (i32 (select (i1 (setult (i32 IntRegs:$src2),
603                                              (i32 IntRegs:$src1))),
604                                  (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>;
605
606 def MAXd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
607                                                     DoubleRegs:$src2),
608               "$dst = max($src2, $src1)",
609               [(set (i64 DoubleRegs:$dst),
610                     (i64 (select (i1 (setlt (i64 DoubleRegs:$src2),
611                                             (i64 DoubleRegs:$src1))),
612                                  (i64 DoubleRegs:$src1),
613                                  (i64 DoubleRegs:$src2))))]>;
614
615 def MAXUd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
616                                                      DoubleRegs:$src2),
617               "$dst = maxu($src2, $src1)",
618               [(set (i64 DoubleRegs:$dst),
619                     (i64 (select (i1 (setult (i64 DoubleRegs:$src2),
620                                              (i64 DoubleRegs:$src1))),
621                                  (i64 DoubleRegs:$src1),
622                                  (i64 DoubleRegs:$src2))))]>;
623
624 // Minimum.
625 def MINw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
626               "$dst = min($src2, $src1)",
627               [(set (i32 IntRegs:$dst),
628                     (i32 (select (i1 (setgt (i32 IntRegs:$src2),
629                                             (i32 IntRegs:$src1))),
630                                  (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>;
631
632 def MINUw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
633               "$dst = minu($src2, $src1)",
634               [(set (i32 IntRegs:$dst),
635                     (i32 (select (i1 (setugt (i32 IntRegs:$src2),
636                                              (i32 IntRegs:$src1))),
637                                  (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>;
638
639 def MINd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
640                                                     DoubleRegs:$src2),
641               "$dst = min($src2, $src1)",
642               [(set (i64 DoubleRegs:$dst),
643                     (i64 (select (i1 (setgt (i64 DoubleRegs:$src2),
644                                             (i64 DoubleRegs:$src1))),
645                                  (i64 DoubleRegs:$src1),
646                                  (i64 DoubleRegs:$src2))))]>;
647
648 def MINUd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
649                                                      DoubleRegs:$src2),
650               "$dst = minu($src2, $src1)",
651               [(set (i64 DoubleRegs:$dst),
652                     (i64 (select (i1 (setugt (i64 DoubleRegs:$src2),
653                                              (i64 DoubleRegs:$src1))),
654                                  (i64 DoubleRegs:$src1),
655                                  (i64 DoubleRegs:$src2))))]>;
656
657 // Subtract.
658 def SUB64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
659                                                      DoubleRegs:$src2),
660                "$dst = sub($src1, $src2)",
661                [(set (i64 DoubleRegs:$dst), (sub (i64 DoubleRegs:$src1),
662                                                  (i64 DoubleRegs:$src2)))]>;
663
664 // Subtract halfword.
665
666 //===----------------------------------------------------------------------===//
667 // ALU64/ALU -
668 //===----------------------------------------------------------------------===//
669
670 //===----------------------------------------------------------------------===//
671 // ALU64/BIT +
672 //===----------------------------------------------------------------------===//
673 //
674 //===----------------------------------------------------------------------===//
675 // ALU64/BIT -
676 //===----------------------------------------------------------------------===//
677
678 //===----------------------------------------------------------------------===//
679 // ALU64/PERM +
680 //===----------------------------------------------------------------------===//
681 //
682 //===----------------------------------------------------------------------===//
683 // ALU64/PERM -
684 //===----------------------------------------------------------------------===//
685
686 //===----------------------------------------------------------------------===//
687 // CR +
688 //===----------------------------------------------------------------------===//
689 // Logical reductions on predicates.
690
691 // Looping instructions.
692
693 // Pipelined looping instructions.
694
695 // Logical operations on predicates.
696 def AND_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2),
697              "$dst = and($src1, $src2)",
698              [(set (i1 PredRegs:$dst), (and (i1 PredRegs:$src1),
699                                             (i1 PredRegs:$src2)))]>;
700
701 let neverHasSideEffects = 1 in
702 def AND_pnotp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1,
703                                                  PredRegs:$src2),
704                 "$dst = and($src1, !$src2)",
705                 []>;
706
707 def ANY_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1),
708              "$dst = any8($src1)",
709              []>;
710
711 def ALL_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1),
712              "$dst = all8($src1)",
713              []>;
714
715 def VITPACK_pp : SInst<(outs IntRegs:$dst), (ins PredRegs:$src1,
716                                                  PredRegs:$src2),
717              "$dst = vitpack($src1, $src2)",
718              []>;
719
720 def VALIGN_rrp : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
721                                                     DoubleRegs:$src2,
722                                                     PredRegs:$src3),
723              "$dst = valignb($src1, $src2, $src3)",
724              []>;
725
726 def VSPLICE_rrp : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
727                                                      DoubleRegs:$src2,
728                                                      PredRegs:$src3),
729              "$dst = vspliceb($src1, $src2, $src3)",
730              []>;
731
732 def MASK_p : SInst<(outs DoubleRegs:$dst), (ins PredRegs:$src1),
733              "$dst = mask($src1)",
734              []>;
735
736 def NOT_p : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1),
737              "$dst = not($src1)",
738              [(set (i1 PredRegs:$dst), (not (i1 PredRegs:$src1)))]>;
739
740 def OR_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2),
741             "$dst = or($src1, $src2)",
742             [(set (i1 PredRegs:$dst), (or (i1 PredRegs:$src1),
743                                           (i1 PredRegs:$src2)))]>;
744
745 def XOR_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2),
746              "$dst = xor($src1, $src2)",
747              [(set (i1 PredRegs:$dst), (xor (i1 PredRegs:$src1),
748                                             (i1 PredRegs:$src2)))]>;
749
750
751 // User control register transfer.
752 //===----------------------------------------------------------------------===//
753 // CR -
754 //===----------------------------------------------------------------------===//
755
756
757 //===----------------------------------------------------------------------===//
758 // J +
759 //===----------------------------------------------------------------------===//
760 // Jump to address.
761 let isBranch = 1, isTerminator=1, isBarrier = 1, isPredicable = 1 in {
762   def JMP : JInst< (outs),
763             (ins brtarget:$offset),
764             "jump $offset",
765             [(br bb:$offset)]>;
766 }
767
768 // if (p0) jump
769 let isBranch = 1, isTerminator=1, Defs = [PC],
770     isPredicated = 1 in {
771   def JMP_c : JInst< (outs),
772                  (ins PredRegs:$src, brtarget:$offset),
773                  "if ($src) jump $offset",
774                  [(brcond (i1 PredRegs:$src), bb:$offset)]>;
775 }
776
777 // if (!p0) jump
778 let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC],
779     isPredicated = 1 in {
780   def JMP_cNot : JInst< (outs),
781                     (ins PredRegs:$src, brtarget:$offset),
782                     "if (!$src) jump $offset",
783                     []>;
784 }
785
786 let isTerminator = 1, isBranch = 1, neverHasSideEffects = 1, Defs = [PC],
787     isPredicated = 1 in {
788   def BRCOND : JInst < (outs), (ins PredRegs:$pred, brtarget:$dst),
789                "if ($pred) jump $dst",
790                []>;
791 }
792
793 // Jump to address conditioned on new predicate.
794 // if (p0) jump:t
795 let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC],
796     isPredicated = 1 in {
797   def JMP_cdnPt : JInst< (outs),
798                    (ins PredRegs:$src, brtarget:$offset),
799                    "if ($src.new) jump:t $offset",
800                    []>;
801 }
802
803 // if (!p0) jump:t
804 let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC],
805     isPredicated = 1 in {
806   def JMP_cdnNotPt : JInst< (outs),
807                       (ins PredRegs:$src, brtarget:$offset),
808                       "if (!$src.new) jump:t $offset",
809                       []>;
810 }
811
812 // Not taken.
813 let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC],
814     isPredicated = 1 in {
815   def JMP_cdnPnt : JInst< (outs),
816                     (ins PredRegs:$src, brtarget:$offset),
817                     "if ($src.new) jump:nt $offset",
818                     []>;
819 }
820
821 // Not taken.
822 let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC],
823     isPredicated = 1 in {
824   def JMP_cdnNotPnt : JInst< (outs),
825                        (ins PredRegs:$src, brtarget:$offset),
826                        "if (!$src.new) jump:nt $offset",
827                        []>;
828 }
829 //===----------------------------------------------------------------------===//
830 // J -
831 //===----------------------------------------------------------------------===//
832
833 //===----------------------------------------------------------------------===//
834 // JR +
835 //===----------------------------------------------------------------------===//
836 def retflag : SDNode<"HexagonISD::RET_FLAG", SDTNone,
837                                [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
838
839 // Jump to address from register.
840 let isPredicable =1, isReturn = 1, isTerminator = 1, isBarrier = 1,
841   Defs = [PC], Uses = [R31] in {
842   def JMPR: JRInst<(outs), (ins),
843                    "jumpr r31",
844                    [(retflag)]>;
845 }
846
847 // Jump to address from register.
848 let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicated = 1,
849   Defs = [PC], Uses = [R31] in {
850   def JMPR_cPt: JRInst<(outs), (ins PredRegs:$src1),
851                        "if ($src1) jumpr r31",
852                        []>;
853 }
854
855 // Jump to address from register.
856 let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicated = 1,
857   Defs = [PC], Uses = [R31] in {
858   def JMPR_cNotPt: JRInst<(outs), (ins PredRegs:$src1),
859                           "if (!$src1) jumpr r31",
860                           []>;
861 }
862
863 //===----------------------------------------------------------------------===//
864 // JR -
865 //===----------------------------------------------------------------------===//
866
867 //===----------------------------------------------------------------------===//
868 // LD +
869 //===----------------------------------------------------------------------===//
870 ///
871 // Load -- MEMri operand
872 multiclass LD_MEMri_Pbase<string mnemonic, RegisterClass RC,
873                           bit isNot, bit isPredNew> {
874   let PNewValue = !if(isPredNew, "new", "") in
875   def NAME : LDInst2<(outs RC:$dst),
876                        (ins PredRegs:$src1, MEMri:$addr),
877             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
878             ") ")#"$dst = "#mnemonic#"($addr)",
879             []>;
880 }
881
882 multiclass LD_MEMri_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
883   let PredSense = !if(PredNot, "false", "true") in {
884     defm _c#NAME : LD_MEMri_Pbase<mnemonic, RC, PredNot, 0>;
885     // Predicate new
886     defm _cdn#NAME : LD_MEMri_Pbase<mnemonic, RC, PredNot, 1>;
887   }
888 }
889
890 let isExtendable = 1, neverHasSideEffects = 1 in
891 multiclass LD_MEMri<string mnemonic, string CextOp, RegisterClass RC,
892                     bits<5> ImmBits, bits<5> PredImmBits> {
893
894   let CextOpcode = CextOp, BaseOpcode = CextOp in {
895     let opExtendable = 2, isExtentSigned = 1, opExtentBits = ImmBits,
896         isPredicable = 1 in
897       def NAME : LDInst2<(outs RC:$dst), (ins MEMri:$addr),
898                    "$dst = "#mnemonic#"($addr)",
899                    []>;
900
901     let opExtendable = 3, isExtentSigned = 0, opExtentBits = PredImmBits,
902         isPredicated = 1 in {
903       defm Pt : LD_MEMri_Pred<mnemonic, RC, 0 >;
904       defm NotPt : LD_MEMri_Pred<mnemonic, RC, 1 >;
905     }
906   }
907 }
908
909 let addrMode = BaseImmOffset, isMEMri = "true" in {
910   defm LDrib: LD_MEMri < "memb", "LDrib", IntRegs, 11, 6>, AddrModeRel;
911   defm LDriub: LD_MEMri < "memub" , "LDriub", IntRegs, 11, 6>, AddrModeRel;
912   defm LDrih: LD_MEMri < "memh", "LDrih", IntRegs, 12, 7>, AddrModeRel;
913   defm LDriuh: LD_MEMri < "memuh", "LDriuh", IntRegs, 12, 7>, AddrModeRel;
914   defm LDriw: LD_MEMri < "memw", "LDriw", IntRegs, 13, 8>, AddrModeRel;
915   defm LDrid: LD_MEMri < "memd", "LDrid", DoubleRegs, 14, 9>, AddrModeRel;
916 }
917
918 def : Pat < (i32 (sextloadi8 ADDRriS11_0:$addr)),
919             (LDrib ADDRriS11_0:$addr) >;
920
921 def : Pat < (i32 (zextloadi8 ADDRriS11_0:$addr)),
922             (LDriub ADDRriS11_0:$addr) >;
923
924 def : Pat < (i32 (sextloadi16 ADDRriS11_1:$addr)),
925             (LDrih ADDRriS11_1:$addr) >;
926
927 def : Pat < (i32 (zextloadi16 ADDRriS11_1:$addr)),
928             (LDriuh ADDRriS11_1:$addr) >;
929
930 def : Pat < (i32 (load ADDRriS11_2:$addr)),
931             (LDriw ADDRriS11_2:$addr) >;
932
933 def : Pat < (i64 (load ADDRriS11_3:$addr)),
934             (LDrid ADDRriS11_3:$addr) >;
935
936
937 // Load - Base with Immediate offset addressing mode
938 multiclass LD_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp,
939                         bit isNot, bit isPredNew> {
940   let PNewValue = !if(isPredNew, "new", "") in
941   def NAME : LDInst2<(outs RC:$dst),
942                      (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3),
943             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
944             ") ")#"$dst = "#mnemonic#"($src2+#$src3)",
945             []>;
946 }
947
948 multiclass LD_Idxd_Pred<string mnemonic, RegisterClass RC, Operand predImmOp,
949                         bit PredNot> {
950   let PredSense = !if(PredNot, "false", "true") in {
951     defm _c#NAME : LD_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 0>;
952     // Predicate new
953     defm _cdn#NAME : LD_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 1>;
954   }
955 }
956
957 let isExtendable = 1, neverHasSideEffects = 1 in
958 multiclass LD_Idxd<string mnemonic, string CextOp, RegisterClass RC,
959                    Operand ImmOp, Operand predImmOp, bits<5> ImmBits,
960                    bits<5> PredImmBits> {
961
962   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
963     let opExtendable = 2, isExtentSigned = 1, opExtentBits = ImmBits,
964         isPredicable = 1, AddedComplexity = 20 in
965       def NAME : LDInst2<(outs RC:$dst), (ins IntRegs:$src1, ImmOp:$offset),
966                    "$dst = "#mnemonic#"($src1+#$offset)",
967                    []>;
968
969     let opExtendable = 3, isExtentSigned = 0, opExtentBits = PredImmBits,
970         isPredicated = 1 in {
971       defm Pt : LD_Idxd_Pred<mnemonic, RC, predImmOp, 0 >;
972       defm NotPt : LD_Idxd_Pred<mnemonic, RC, predImmOp, 1 >;
973     }
974   }
975 }
976
977 let addrMode = BaseImmOffset in {
978   defm LDrib_indexed: LD_Idxd <"memb", "LDrib", IntRegs, s11_0Ext, u6_0Ext,
979                                11, 6>, AddrModeRel;
980   defm LDriub_indexed: LD_Idxd <"memub" , "LDriub", IntRegs, s11_0Ext, u6_0Ext,
981                                 11, 6>, AddrModeRel;
982   defm LDrih_indexed: LD_Idxd <"memh", "LDrih", IntRegs, s11_1Ext, u6_1Ext,
983                                12, 7>, AddrModeRel;
984   defm LDriuh_indexed: LD_Idxd <"memuh", "LDriuh", IntRegs, s11_1Ext, u6_1Ext,
985                                 12, 7>, AddrModeRel;
986   defm LDriw_indexed: LD_Idxd <"memw", "LDriw", IntRegs, s11_2Ext, u6_2Ext,
987                                13, 8>, AddrModeRel;
988   defm LDrid_indexed: LD_Idxd <"memd", "LDrid", DoubleRegs, s11_3Ext, u6_3Ext,
989                                14, 9>, AddrModeRel;
990 }
991
992 let AddedComplexity = 20 in {
993 def : Pat < (i32 (sextloadi8 (add IntRegs:$src1, s11_0ExtPred:$offset))),
994             (LDrib_indexed IntRegs:$src1, s11_0ExtPred:$offset) >;
995
996 def : Pat < (i32 (zextloadi8 (add IntRegs:$src1, s11_0ExtPred:$offset))),
997             (LDriub_indexed IntRegs:$src1, s11_0ExtPred:$offset) >;
998
999 def : Pat < (i32 (sextloadi16 (add IntRegs:$src1, s11_1ExtPred:$offset))),
1000             (LDrih_indexed IntRegs:$src1, s11_1ExtPred:$offset) >;
1001
1002 def : Pat < (i32 (zextloadi16 (add IntRegs:$src1, s11_1ExtPred:$offset))),
1003             (LDriuh_indexed IntRegs:$src1, s11_1ExtPred:$offset) >;
1004
1005 def : Pat < (i32 (load (add IntRegs:$src1, s11_2ExtPred:$offset))),
1006             (LDriw_indexed IntRegs:$src1, s11_2ExtPred:$offset) >;
1007
1008 def : Pat < (i64 (load (add IntRegs:$src1, s11_3ExtPred:$offset))),
1009             (LDrid_indexed IntRegs:$src1, s11_3ExtPred:$offset) >;
1010 }
1011
1012 let neverHasSideEffects = 1 in
1013 def LDrid_GP : LDInst2<(outs DoubleRegs:$dst),
1014             (ins globaladdress:$global, u16Imm:$offset),
1015             "$dst = memd(#$global+$offset)",
1016             []>,
1017             Requires<[NoV4T]>;
1018
1019 let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
1020 def LDd_GP : LDInst2<(outs DoubleRegs:$dst),
1021             (ins globaladdress:$global),
1022             "$dst = memd(#$global)",
1023             []>,
1024             Requires<[NoV4T]>;
1025
1026 //===----------------------------------------------------------------------===//
1027 // Post increment load
1028 // Make sure that in post increment load, the first operand is always the post
1029 // increment operand.
1030 //===----------------------------------------------------------------------===//
1031
1032 multiclass LD_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
1033                             bit isNot, bit isPredNew> {
1034   let PNewValue = !if(isPredNew, "new", "") in
1035   def NAME : LDInst2PI<(outs RC:$dst, IntRegs:$dst2),
1036                        (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset),
1037             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1038             ") ")#"$dst = "#mnemonic#"($src2++#$offset)",
1039             [],
1040             "$src2 = $dst2">;
1041 }
1042
1043 multiclass LD_PostInc_Pred<string mnemonic, RegisterClass RC,
1044                            Operand ImmOp, bit PredNot> {
1045   let PredSense = !if(PredNot, "false", "true") in {
1046     defm _c#NAME : LD_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>;
1047     // Predicate new
1048     let Predicates = [HasV4T], validSubTargets = HasV4SubT in
1049     defm _cdn#NAME#_V4 : LD_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 1>;
1050   }
1051 }
1052
1053 multiclass LD_PostInc<string mnemonic, string BaseOp, RegisterClass RC,
1054                       Operand ImmOp> {
1055
1056   let BaseOpcode = "POST_"#BaseOp in {
1057     let isPredicable = 1 in
1058     def NAME : LDInst2PI<(outs RC:$dst, IntRegs:$dst2),
1059                          (ins IntRegs:$src1, ImmOp:$offset),
1060                  "$dst = "#mnemonic#"($src1++#$offset)",
1061                  [],
1062                  "$src1 = $dst2">;
1063
1064     let isPredicated = 1 in {
1065       defm Pt : LD_PostInc_Pred<mnemonic, RC, ImmOp, 0 >;
1066       defm NotPt : LD_PostInc_Pred<mnemonic, RC, ImmOp, 1 >;
1067     }
1068   }
1069 }
1070
1071 let hasCtrlDep = 1, neverHasSideEffects = 1 in {
1072   defm POST_LDrib : LD_PostInc<"memb", "LDrib", IntRegs, s4_0Imm>,
1073                     PredNewRel;
1074   defm POST_LDriub : LD_PostInc<"memub", "LDriub", IntRegs, s4_0Imm>,
1075                     PredNewRel;
1076   defm POST_LDrih : LD_PostInc<"memh", "LDrih", IntRegs, s4_1Imm>,
1077                     PredNewRel;
1078   defm POST_LDriuh : LD_PostInc<"memuh", "LDriuh", IntRegs, s4_1Imm>,
1079                     PredNewRel;
1080   defm POST_LDriw : LD_PostInc<"memw", "LDriw", IntRegs, s4_2Imm>,
1081                     PredNewRel;
1082   defm POST_LDrid : LD_PostInc<"memd", "LDrid", DoubleRegs, s4_3Imm>,
1083                     PredNewRel;
1084 }
1085
1086 def : Pat< (i32 (extloadi1 ADDRriS11_0:$addr)),
1087            (i32 (LDrib ADDRriS11_0:$addr)) >;
1088
1089 // Load byte any-extend.
1090 def : Pat < (i32 (extloadi8 ADDRriS11_0:$addr)),
1091             (i32 (LDrib ADDRriS11_0:$addr)) >;
1092
1093 // Indexed load byte any-extend.
1094 let AddedComplexity = 20 in
1095 def : Pat < (i32 (extloadi8 (add IntRegs:$src1, s11_0ImmPred:$offset))),
1096             (i32 (LDrib_indexed IntRegs:$src1, s11_0ImmPred:$offset)) >;
1097
1098 let neverHasSideEffects = 1 in
1099 def LDrib_GP : LDInst2<(outs IntRegs:$dst),
1100             (ins globaladdress:$global, u16Imm:$offset),
1101             "$dst = memb(#$global+$offset)",
1102             []>,
1103             Requires<[NoV4T]>;
1104
1105 let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
1106 def LDb_GP : LDInst2<(outs IntRegs:$dst),
1107             (ins globaladdress:$global),
1108             "$dst = memb(#$global)",
1109             []>,
1110             Requires<[NoV4T]>;
1111
1112 let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
1113 def LDub_GP : LDInst2<(outs IntRegs:$dst),
1114             (ins globaladdress:$global),
1115             "$dst = memub(#$global)",
1116             []>,
1117             Requires<[NoV4T]>;
1118
1119 def : Pat < (i32 (extloadi16 ADDRriS11_1:$addr)),
1120             (i32 (LDrih ADDRriS11_1:$addr))>;
1121
1122 let AddedComplexity = 20 in
1123 def : Pat < (i32 (extloadi16 (add IntRegs:$src1, s11_1ImmPred:$offset))),
1124             (i32 (LDrih_indexed IntRegs:$src1, s11_1ImmPred:$offset)) >;
1125
1126 let neverHasSideEffects = 1 in
1127 def LDrih_GP : LDInst2<(outs IntRegs:$dst),
1128             (ins globaladdress:$global, u16Imm:$offset),
1129             "$dst = memh(#$global+$offset)",
1130             []>,
1131             Requires<[NoV4T]>;
1132
1133 let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
1134 def LDh_GP : LDInst2<(outs IntRegs:$dst),
1135             (ins globaladdress:$global),
1136             "$dst = memh(#$global)",
1137             []>,
1138             Requires<[NoV4T]>;
1139
1140 let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
1141 def LDuh_GP : LDInst2<(outs IntRegs:$dst),
1142             (ins globaladdress:$global),
1143             "$dst = memuh(#$global)",
1144             []>,
1145             Requires<[NoV4T]>;
1146
1147 let AddedComplexity = 10 in
1148 def : Pat < (i32 (zextloadi1 ADDRriS11_0:$addr)),
1149             (i32 (LDriub ADDRriS11_0:$addr))>;
1150
1151 let AddedComplexity = 20 in
1152 def : Pat < (i32 (zextloadi1 (add IntRegs:$src1, s11_0ImmPred:$offset))),
1153             (i32 (LDriub_indexed IntRegs:$src1, s11_0ImmPred:$offset))>;
1154
1155 let neverHasSideEffects = 1 in
1156 def LDriub_GP : LDInst2<(outs IntRegs:$dst),
1157             (ins globaladdress:$global, u16Imm:$offset),
1158             "$dst = memub(#$global+$offset)",
1159             []>,
1160             Requires<[NoV4T]>;
1161
1162 // Load unsigned halfword.
1163 let neverHasSideEffects = 1 in
1164 def LDriuh_GP : LDInst2<(outs IntRegs:$dst),
1165             (ins globaladdress:$global, u16Imm:$offset),
1166             "$dst = memuh(#$global+$offset)",
1167             []>,
1168             Requires<[NoV4T]>;
1169
1170 // Load predicate.
1171 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13,
1172 isPseudo = 1, Defs = [R10,R11,D5], neverHasSideEffects = 1 in
1173 def LDriw_pred : LDInst2<(outs PredRegs:$dst),
1174             (ins MEMri:$addr),
1175             "Error; should not emit",
1176             []>;
1177
1178 // Indexed load.
1179 let neverHasSideEffects = 1 in
1180 def LDriw_GP : LDInst2<(outs IntRegs:$dst),
1181             (ins globaladdress:$global, u16Imm:$offset),
1182             "$dst = memw(#$global+$offset)",
1183             []>,
1184             Requires<[NoV4T]>;
1185
1186 let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
1187 def LDw_GP : LDInst2<(outs IntRegs:$dst),
1188             (ins globaladdress:$global),
1189             "$dst = memw(#$global)",
1190             []>,
1191             Requires<[NoV4T]>;
1192
1193 // Deallocate stack frame.
1194 let Defs = [R29, R30, R31], Uses = [R29], neverHasSideEffects = 1 in {
1195   def DEALLOCFRAME : LDInst2<(outs), (ins),
1196                      "deallocframe",
1197                      []>;
1198 }
1199
1200 // Load and unpack bytes to halfwords.
1201 //===----------------------------------------------------------------------===//
1202 // LD -
1203 //===----------------------------------------------------------------------===//
1204
1205 //===----------------------------------------------------------------------===//
1206 // MTYPE/ALU +
1207 //===----------------------------------------------------------------------===//
1208 //===----------------------------------------------------------------------===//
1209 // MTYPE/ALU -
1210 //===----------------------------------------------------------------------===//
1211
1212 //===----------------------------------------------------------------------===//
1213 // MTYPE/COMPLEX +
1214 //===----------------------------------------------------------------------===//
1215 //===----------------------------------------------------------------------===//
1216 // MTYPE/COMPLEX -
1217 //===----------------------------------------------------------------------===//
1218
1219 //===----------------------------------------------------------------------===//
1220 // MTYPE/MPYH +
1221 //===----------------------------------------------------------------------===//
1222 // Multiply and use lower result.
1223 // Rd=+mpyi(Rs,#u8)
1224 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 8 in
1225 def MPYI_riu : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u8Ext:$src2),
1226               "$dst =+ mpyi($src1, #$src2)",
1227               [(set (i32 IntRegs:$dst), (mul (i32 IntRegs:$src1),
1228                                              u8ExtPred:$src2))]>;
1229
1230 // Rd=-mpyi(Rs,#u8)
1231 def MPYI_rin : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u8Imm:$src2),
1232               "$dst =- mpyi($src1, #$src2)",
1233               [(set (i32 IntRegs:$dst), (ineg (mul (i32 IntRegs:$src1),
1234                                                    u8ImmPred:$src2)))]>;
1235
1236 // Rd=mpyi(Rs,#m9)
1237 // s9 is NOT the same as m9 - but it works.. so far.
1238 // Assembler maps to either Rd=+mpyi(Rs,#u8 or Rd=-mpyi(Rs,#u8)
1239 // depending on the value of m9. See Arch Spec.
1240 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 9,
1241 CextOpcode = "MPYI", InputType = "imm" in
1242 def MPYI_ri : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, s9Ext:$src2),
1243               "$dst = mpyi($src1, #$src2)",
1244               [(set (i32 IntRegs:$dst), (mul (i32 IntRegs:$src1),
1245                                              s9ExtPred:$src2))]>, ImmRegRel;
1246
1247 // Rd=mpyi(Rs,Rt)
1248 let CextOpcode = "MPYI", InputType = "reg" in
1249 def MPYI : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1250            "$dst = mpyi($src1, $src2)",
1251            [(set (i32 IntRegs:$dst), (mul (i32 IntRegs:$src1),
1252                                           (i32 IntRegs:$src2)))]>, ImmRegRel;
1253
1254 // Rx+=mpyi(Rs,#u8)
1255 let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 8,
1256 CextOpcode = "MPYI_acc", InputType = "imm" in
1257 def MPYI_acc_ri : MInst_acc<(outs IntRegs:$dst),
1258             (ins IntRegs:$src1, IntRegs:$src2, u8Ext:$src3),
1259             "$dst += mpyi($src2, #$src3)",
1260             [(set (i32 IntRegs:$dst),
1261                   (add (mul (i32 IntRegs:$src2), u8ExtPred:$src3),
1262                        (i32 IntRegs:$src1)))],
1263             "$src1 = $dst">, ImmRegRel;
1264
1265 // Rx+=mpyi(Rs,Rt)
1266 let CextOpcode = "MPYI_acc", InputType = "reg" in
1267 def MPYI_acc_rr : MInst_acc<(outs IntRegs:$dst),
1268             (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
1269             "$dst += mpyi($src2, $src3)",
1270             [(set (i32 IntRegs:$dst),
1271                   (add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
1272                        (i32 IntRegs:$src1)))],
1273             "$src1 = $dst">, ImmRegRel;
1274
1275 // Rx-=mpyi(Rs,#u8)
1276 let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 8 in
1277 def MPYI_sub_ri : MInst_acc<(outs IntRegs:$dst),
1278             (ins IntRegs:$src1, IntRegs:$src2, u8Ext:$src3),
1279             "$dst -= mpyi($src2, #$src3)",
1280             [(set (i32 IntRegs:$dst),
1281                   (sub (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
1282                                                  u8ExtPred:$src3)))],
1283             "$src1 = $dst">;
1284
1285 // Multiply and use upper result.
1286 // Rd=mpy(Rs,Rt.H):<<1:rnd:sat
1287 // Rd=mpy(Rs,Rt.L):<<1:rnd:sat
1288 // Rd=mpy(Rs,Rt)
1289 def MPY : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1290           "$dst = mpy($src1, $src2)",
1291           [(set (i32 IntRegs:$dst), (mulhs (i32 IntRegs:$src1),
1292                                            (i32 IntRegs:$src2)))]>;
1293
1294 // Rd=mpy(Rs,Rt):rnd
1295 // Rd=mpyu(Rs,Rt)
1296 def MPYU : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1297            "$dst = mpyu($src1, $src2)",
1298            [(set (i32 IntRegs:$dst), (mulhu (i32 IntRegs:$src1),
1299                                             (i32 IntRegs:$src2)))]>;
1300
1301 // Multiply and use full result.
1302 // Rdd=mpyu(Rs,Rt)
1303 def MPYU64 : MInst<(outs DoubleRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1304              "$dst = mpyu($src1, $src2)",
1305              [(set (i64 DoubleRegs:$dst),
1306                    (mul (i64 (anyext (i32 IntRegs:$src1))),
1307                         (i64 (anyext (i32 IntRegs:$src2)))))]>;
1308
1309 // Rdd=mpy(Rs,Rt)
1310 def MPY64 : MInst<(outs DoubleRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1311              "$dst = mpy($src1, $src2)",
1312              [(set (i64 DoubleRegs:$dst),
1313                    (mul (i64 (sext (i32 IntRegs:$src1))),
1314                         (i64 (sext (i32 IntRegs:$src2)))))]>;
1315
1316 // Multiply and accumulate, use full result.
1317 // Rxx[+-]=mpy(Rs,Rt)
1318 // Rxx+=mpy(Rs,Rt)
1319 def MPY64_acc : MInst_acc<(outs DoubleRegs:$dst),
1320             (ins DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3),
1321             "$dst += mpy($src2, $src3)",
1322             [(set (i64 DoubleRegs:$dst),
1323             (add (mul (i64 (sext (i32 IntRegs:$src2))),
1324                       (i64 (sext (i32 IntRegs:$src3)))),
1325                  (i64 DoubleRegs:$src1)))],
1326             "$src1 = $dst">;
1327
1328 // Rxx-=mpy(Rs,Rt)
1329 def MPY64_sub : MInst_acc<(outs DoubleRegs:$dst),
1330             (ins DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3),
1331             "$dst -= mpy($src2, $src3)",
1332             [(set (i64 DoubleRegs:$dst),
1333                   (sub (i64 DoubleRegs:$src1),
1334                        (mul (i64 (sext (i32 IntRegs:$src2))),
1335                             (i64 (sext (i32 IntRegs:$src3))))))],
1336             "$src1 = $dst">;
1337
1338 // Rxx[+-]=mpyu(Rs,Rt)
1339 // Rxx+=mpyu(Rs,Rt)
1340 def MPYU64_acc : MInst_acc<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
1341                             IntRegs:$src2, IntRegs:$src3),
1342              "$dst += mpyu($src2, $src3)",
1343              [(set (i64 DoubleRegs:$dst),
1344                    (add (mul (i64 (anyext (i32 IntRegs:$src2))),
1345                              (i64 (anyext (i32 IntRegs:$src3)))),
1346                         (i64 DoubleRegs:$src1)))], "$src1 = $dst">;
1347
1348 // Rxx-=mpyu(Rs,Rt)
1349 def MPYU64_sub : MInst_acc<(outs DoubleRegs:$dst),
1350             (ins DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3),
1351             "$dst -= mpyu($src2, $src3)",
1352             [(set (i64 DoubleRegs:$dst),
1353                   (sub (i64 DoubleRegs:$src1),
1354                        (mul (i64 (anyext (i32 IntRegs:$src2))),
1355                             (i64 (anyext (i32 IntRegs:$src3))))))],
1356             "$src1 = $dst">;
1357
1358
1359 let InputType = "reg", CextOpcode = "ADD_acc" in
1360 def ADDrr_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
1361                             IntRegs:$src2, IntRegs:$src3),
1362              "$dst += add($src2, $src3)",
1363              [(set (i32 IntRegs:$dst), (add (add (i32 IntRegs:$src2),
1364                                                  (i32 IntRegs:$src3)),
1365                                             (i32 IntRegs:$src1)))],
1366              "$src1 = $dst">, ImmRegRel;
1367
1368 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 8,
1369 InputType = "imm", CextOpcode = "ADD_acc" in
1370 def ADDri_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
1371                             IntRegs:$src2, s8Ext:$src3),
1372              "$dst += add($src2, #$src3)",
1373              [(set (i32 IntRegs:$dst), (add (add (i32 IntRegs:$src2),
1374                                                  s8_16ExtPred:$src3),
1375                                             (i32 IntRegs:$src1)))],
1376              "$src1 = $dst">, ImmRegRel;
1377
1378 let CextOpcode = "SUB_acc", InputType = "reg" in
1379 def SUBrr_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
1380                             IntRegs:$src2, IntRegs:$src3),
1381              "$dst -= add($src2, $src3)",
1382              [(set (i32 IntRegs:$dst),
1383                    (sub (i32 IntRegs:$src1), (add (i32 IntRegs:$src2),
1384                                                   (i32 IntRegs:$src3))))],
1385              "$src1 = $dst">, ImmRegRel;
1386
1387 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 8,
1388 CextOpcode = "SUB_acc", InputType = "imm" in
1389 def SUBri_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
1390                             IntRegs:$src2, s8Ext:$src3),
1391              "$dst -= add($src2, #$src3)",
1392              [(set (i32 IntRegs:$dst), (sub (i32 IntRegs:$src1),
1393                                             (add (i32 IntRegs:$src2),
1394                                                  s8_16ExtPred:$src3)))],
1395              "$src1 = $dst">, ImmRegRel;
1396
1397 //===----------------------------------------------------------------------===//
1398 // MTYPE/MPYH -
1399 //===----------------------------------------------------------------------===//
1400
1401 //===----------------------------------------------------------------------===//
1402 // MTYPE/MPYS +
1403 //===----------------------------------------------------------------------===//
1404 //===----------------------------------------------------------------------===//
1405 // MTYPE/MPYS -
1406 //===----------------------------------------------------------------------===//
1407
1408 //===----------------------------------------------------------------------===//
1409 // MTYPE/VB +
1410 //===----------------------------------------------------------------------===//
1411 //===----------------------------------------------------------------------===//
1412 // MTYPE/VB -
1413 //===----------------------------------------------------------------------===//
1414
1415 //===----------------------------------------------------------------------===//
1416 // MTYPE/VH  +
1417 //===----------------------------------------------------------------------===//
1418 //===----------------------------------------------------------------------===//
1419 // MTYPE/VH  -
1420 //===----------------------------------------------------------------------===//
1421
1422 //===----------------------------------------------------------------------===//
1423 // ST +
1424 //===----------------------------------------------------------------------===//
1425 ///
1426 /// Assumptions::: ****** DO NOT IGNORE ********
1427 /// 1. Make sure that in post increment store, the zero'th operand is always the
1428 ///    post increment operand.
1429 /// 2. Make sure that the store value operand(Rt/Rtt) in a store is always the
1430 ///    last operand.
1431 ///
1432 // Store doubleword.
1433
1434 let neverHasSideEffects = 1 in
1435 def STrid_GP : STInst2<(outs),
1436             (ins globaladdress:$global, u16Imm:$offset, DoubleRegs:$src),
1437             "memd(#$global+$offset) = $src",
1438             []>,
1439             Requires<[NoV4T]>;
1440
1441 let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
1442 def STd_GP : STInst2<(outs),
1443             (ins globaladdress:$global, DoubleRegs:$src),
1444             "memd(#$global) = $src",
1445             []>,
1446             Requires<[NoV4T]>;
1447
1448 //===----------------------------------------------------------------------===//
1449 // Post increment store
1450 //===----------------------------------------------------------------------===//
1451
1452 multiclass ST_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
1453                             bit isNot, bit isPredNew> {
1454   let PNewValue = !if(isPredNew, "new", "") in
1455   def NAME : STInst2PI<(outs IntRegs:$dst),
1456             (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3),
1457             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1458             ") ")#mnemonic#"($src2++#$offset) = $src3",
1459             [],
1460             "$src2 = $dst">;
1461 }
1462
1463 multiclass ST_PostInc_Pred<string mnemonic, RegisterClass RC,
1464                            Operand ImmOp, bit PredNot> {
1465   let PredSense = !if(PredNot, "false", "true") in {
1466     defm _c#NAME# : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>;
1467     // Predicate new
1468     let Predicates = [HasV4T], validSubTargets = HasV4SubT in
1469     defm _cdn#NAME#_V4 : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 1>;
1470   }
1471 }
1472
1473 let hasCtrlDep = 1, isNVStorable = 1, neverHasSideEffects = 1 in
1474 multiclass ST_PostInc<string mnemonic, string BaseOp, RegisterClass RC,
1475                       Operand ImmOp> {
1476
1477   let hasCtrlDep = 1, BaseOpcode = "POST_"#BaseOp in {
1478     let isPredicable = 1 in
1479     def NAME : STInst2PI<(outs IntRegs:$dst),
1480                 (ins IntRegs:$src1, ImmOp:$offset, RC:$src2),
1481                 #mnemonic#"($src1++#$offset) = $src2",
1482                 [],
1483                 "$src1 = $dst">;
1484
1485     let isPredicated = 1 in {
1486       defm Pt : ST_PostInc_Pred<mnemonic, RC, ImmOp, 0 >;
1487       defm NotPt : ST_PostInc_Pred<mnemonic, RC, ImmOp, 1 >;
1488     }
1489   }
1490 }
1491
1492 defm POST_STbri: ST_PostInc <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel;
1493 defm POST_SThri: ST_PostInc <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel;
1494 defm POST_STwri: ST_PostInc <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
1495
1496 let isNVStorable = 0 in
1497 defm POST_STdri: ST_PostInc <"memd", "STrid", DoubleRegs, s4_3Imm>, AddrModeRel;
1498
1499 def : Pat<(post_truncsti8 (i32 IntRegs:$src1), IntRegs:$src2,
1500                            s4_3ImmPred:$offset),
1501           (POST_STbri IntRegs:$src2, s4_0ImmPred:$offset, IntRegs:$src1)>;
1502
1503 def : Pat<(post_truncsti16 (i32 IntRegs:$src1), IntRegs:$src2,
1504                             s4_3ImmPred:$offset),
1505           (POST_SThri IntRegs:$src2, s4_1ImmPred:$offset, IntRegs:$src1)>;
1506
1507 def : Pat<(post_store (i32 IntRegs:$src1), IntRegs:$src2, s4_2ImmPred:$offset),
1508           (POST_STwri IntRegs:$src2, s4_1ImmPred:$offset, IntRegs:$src1)>;
1509
1510 def : Pat<(post_store (i64 DoubleRegs:$src1), IntRegs:$src2,
1511                        s4_3ImmPred:$offset),
1512           (POST_STdri IntRegs:$src2, s4_3ImmPred:$offset, DoubleRegs:$src1)>;
1513
1514 //===----------------------------------------------------------------------===//
1515 // multiclass for the store instructions with MEMri operand.
1516 //===----------------------------------------------------------------------===//
1517 multiclass ST_MEMri_Pbase<string mnemonic, RegisterClass RC, bit isNot,
1518                           bit isPredNew> {
1519   let PNewValue = !if(isPredNew, "new", "") in
1520   def NAME : STInst2<(outs),
1521             (ins PredRegs:$src1, MEMri:$addr, RC: $src2),
1522             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1523             ") ")#mnemonic#"($addr) = $src2",
1524             []>;
1525 }
1526
1527 multiclass ST_MEMri_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
1528   let PredSense = !if(PredNot, "false", "true") in {
1529     defm _c#NAME : ST_MEMri_Pbase<mnemonic, RC, PredNot, 0>;
1530
1531     // Predicate new
1532     let validSubTargets = HasV4SubT, Predicates = [HasV4T] in
1533     defm _cdn#NAME#_V4 : ST_MEMri_Pbase<mnemonic, RC, PredNot, 1>;
1534   }
1535 }
1536
1537 let isExtendable = 1, isNVStorable = 1, neverHasSideEffects = 1 in
1538 multiclass ST_MEMri<string mnemonic, string CextOp, RegisterClass RC,
1539                     bits<5> ImmBits, bits<5> PredImmBits> {
1540
1541   let CextOpcode = CextOp, BaseOpcode = CextOp in {
1542     let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
1543          isPredicable = 1 in
1544     def NAME : STInst2<(outs),
1545             (ins MEMri:$addr, RC:$src),
1546             mnemonic#"($addr) = $src",
1547             []>;
1548
1549     let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
1550         isPredicated = 1 in {
1551       defm Pt : ST_MEMri_Pred<mnemonic, RC, 0>;
1552       defm NotPt : ST_MEMri_Pred<mnemonic, RC, 1>;
1553     }
1554   }
1555 }
1556
1557 let addrMode = BaseImmOffset, isMEMri = "true" in {
1558   defm STrib: ST_MEMri < "memb", "STrib", IntRegs, 11, 6>, AddrModeRel;
1559   defm STrih: ST_MEMri < "memh", "STrih", IntRegs, 12, 7>, AddrModeRel;
1560   defm STriw: ST_MEMri < "memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
1561
1562   let isNVStorable = 0 in
1563   defm STrid: ST_MEMri < "memd", "STrid", DoubleRegs, 14, 9>, AddrModeRel;
1564 }
1565
1566 def : Pat<(truncstorei8 (i32 IntRegs:$src1), ADDRriS11_0:$addr),
1567           (STrib ADDRriS11_0:$addr, (i32 IntRegs:$src1))>;
1568
1569 def : Pat<(truncstorei16 (i32 IntRegs:$src1), ADDRriS11_1:$addr),
1570           (STrih ADDRriS11_1:$addr, (i32 IntRegs:$src1))>;
1571
1572 def : Pat<(store (i32 IntRegs:$src1), ADDRriS11_2:$addr),
1573           (STriw ADDRriS11_2:$addr, (i32 IntRegs:$src1))>;
1574
1575 def : Pat<(store (i64 DoubleRegs:$src1), ADDRriS11_3:$addr),
1576           (STrid ADDRriS11_3:$addr, (i64 DoubleRegs:$src1))>;
1577
1578
1579 //===----------------------------------------------------------------------===//
1580 // multiclass for the store instructions with base+immediate offset
1581 // addressing mode
1582 //===----------------------------------------------------------------------===//
1583 multiclass ST_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp,
1584                         bit isNot, bit isPredNew> {
1585   let PNewValue = !if(isPredNew, "new", "") in
1586   def NAME : STInst2<(outs),
1587             (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4),
1588             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1589             ") ")#mnemonic#"($src2+#$src3) = $src4",
1590             []>;
1591 }
1592
1593 multiclass ST_Idxd_Pred<string mnemonic, RegisterClass RC, Operand predImmOp,
1594                         bit PredNot> {
1595   let PredSense = !if(PredNot, "false", "true"), isPredicated = 1 in {
1596     defm _c#NAME : ST_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 0>;
1597
1598     // Predicate new
1599     let validSubTargets = HasV4SubT, Predicates = [HasV4T] in
1600     defm _cdn#NAME#_V4 : ST_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 1>;
1601   }
1602 }
1603
1604 let isExtendable = 1, isNVStorable = 1, neverHasSideEffects = 1 in
1605 multiclass ST_Idxd<string mnemonic, string CextOp, RegisterClass RC,
1606                    Operand ImmOp, Operand predImmOp, bits<5> ImmBits,
1607                    bits<5> PredImmBits> {
1608
1609   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
1610     let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
1611          isPredicable = 1 in
1612     def NAME : STInst2<(outs),
1613             (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
1614             mnemonic#"($src1+#$src2) = $src3",
1615             []>;
1616
1617     let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits in {
1618       defm Pt : ST_Idxd_Pred<mnemonic, RC, predImmOp, 0>;
1619       defm NotPt : ST_Idxd_Pred<mnemonic, RC, predImmOp, 1>;
1620     }
1621   }
1622 }
1623
1624 let addrMode = BaseImmOffset, InputType = "reg" in {
1625   defm STrib_indexed: ST_Idxd < "memb", "STrib", IntRegs, s11_0Ext,
1626                                 u6_0Ext, 11, 6>, AddrModeRel, ImmRegRel;
1627   defm STrih_indexed: ST_Idxd < "memh", "STrih", IntRegs, s11_1Ext,
1628                                 u6_1Ext, 12, 7>, AddrModeRel, ImmRegRel;
1629   defm STriw_indexed: ST_Idxd < "memw", "STriw", IntRegs, s11_2Ext,
1630                                 u6_2Ext, 13, 8>, AddrModeRel, ImmRegRel;
1631   let isNVStorable = 0 in
1632   defm STrid_indexed: ST_Idxd < "memd", "STrid", DoubleRegs, s11_3Ext,
1633                                 u6_3Ext, 14, 9>, AddrModeRel;
1634 }
1635
1636 let AddedComplexity = 10 in {
1637 def : Pat<(truncstorei8 (i32 IntRegs:$src1), (add IntRegs:$src2,
1638                                                   s11_0ExtPred:$offset)),
1639           (STrib_indexed IntRegs:$src2, s11_0ImmPred:$offset,
1640                          (i32 IntRegs:$src1))>;
1641
1642 def : Pat<(truncstorei16 (i32 IntRegs:$src1), (add IntRegs:$src2,
1643                                                    s11_1ExtPred:$offset)),
1644           (STrih_indexed IntRegs:$src2, s11_1ImmPred:$offset,
1645                          (i32 IntRegs:$src1))>;
1646
1647 def : Pat<(store (i32 IntRegs:$src1), (add IntRegs:$src2,
1648                                            s11_2ExtPred:$offset)),
1649           (STriw_indexed IntRegs:$src2, s11_2ImmPred:$offset,
1650                          (i32 IntRegs:$src1))>;
1651
1652 def : Pat<(store (i64 DoubleRegs:$src1), (add IntRegs:$src2,
1653                                               s11_3ExtPred:$offset)),
1654           (STrid_indexed IntRegs:$src2, s11_3ImmPred:$offset,
1655                          (i64 DoubleRegs:$src1))>;
1656 }
1657
1658 // memb(gp+#u16:0)=Rt
1659 let neverHasSideEffects = 1 in
1660 def STrib_GP : STInst2<(outs),
1661             (ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
1662             "memb(#$global+$offset) = $src",
1663             []>,
1664             Requires<[NoV4T]>;
1665
1666 // memb(#global)=Rt
1667 let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
1668 def STb_GP : STInst2<(outs),
1669             (ins globaladdress:$global, IntRegs:$src),
1670             "memb(#$global) = $src",
1671             []>,
1672             Requires<[NoV4T]>;
1673
1674 let neverHasSideEffects = 1 in
1675 def STrih_GP : STInst2<(outs),
1676             (ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
1677             "memh(#$global+$offset) = $src",
1678             []>,
1679             Requires<[NoV4T]>;
1680
1681 let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
1682 def STh_GP   : STInst2<(outs),
1683             (ins globaladdress:$global, IntRegs:$src),
1684             "memh(#$global) = $src",
1685             []>,
1686             Requires<[NoV4T]>;
1687
1688 // memh(Rx++#s4:1)=Rt.H
1689
1690 // Store word.
1691 // Store predicate.
1692 let Defs = [R10,R11,D5], neverHasSideEffects = 1 in
1693 def STriw_pred : STInst2<(outs),
1694             (ins MEMri:$addr, PredRegs:$src1),
1695             "Error; should not emit",
1696             []>;
1697
1698 let neverHasSideEffects = 1 in
1699 def STriw_GP : STInst2<(outs),
1700             (ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
1701             "memw(#$global+$offset) = $src",
1702             []>,
1703             Requires<[NoV4T]>;
1704
1705 let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
1706 def STw_GP : STInst2<(outs),
1707             (ins globaladdress:$global, IntRegs:$src),
1708             "memw(#$global) = $src",
1709             []>,
1710             Requires<[NoV4T]>;
1711
1712 // Allocate stack frame.
1713 let Defs = [R29, R30], Uses = [R31, R30], neverHasSideEffects = 1 in {
1714   def ALLOCFRAME : STInst2<(outs),
1715              (ins i32imm:$amt),
1716              "allocframe(#$amt)",
1717              []>;
1718 }
1719 //===----------------------------------------------------------------------===//
1720 // ST -
1721 //===----------------------------------------------------------------------===//
1722
1723 //===----------------------------------------------------------------------===//
1724 // STYPE/ALU +
1725 //===----------------------------------------------------------------------===//
1726 // Logical NOT.
1727 def NOT_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1),
1728                "$dst = not($src1)",
1729                [(set (i64 DoubleRegs:$dst), (not (i64 DoubleRegs:$src1)))]>;
1730
1731
1732 // Sign extend word to doubleword.
1733 def SXTW : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src1),
1734            "$dst = sxtw($src1)",
1735            [(set (i64 DoubleRegs:$dst), (sext (i32 IntRegs:$src1)))]>;
1736 //===----------------------------------------------------------------------===//
1737 // STYPE/ALU -
1738 //===----------------------------------------------------------------------===//
1739
1740 //===----------------------------------------------------------------------===//
1741 // STYPE/BIT +
1742 //===----------------------------------------------------------------------===//
1743 // clrbit.
1744 def CLRBIT : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1745             "$dst = clrbit($src1, #$src2)",
1746             [(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1),
1747                                            (not
1748                                               (shl 1, u5ImmPred:$src2))))]>;
1749
1750 def CLRBIT_31 : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1751             "$dst = clrbit($src1, #$src2)",
1752             []>;
1753
1754 // Map from r0 = and(r1, 2147483647) to r0 = clrbit(r1, #31).
1755 def : Pat <(and (i32 IntRegs:$src1), 2147483647),
1756       (CLRBIT_31 (i32 IntRegs:$src1), 31)>;
1757
1758 // setbit.
1759 def SETBIT : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1760             "$dst = setbit($src1, #$src2)",
1761             [(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1),
1762                                           (shl 1, u5ImmPred:$src2)))]>;
1763
1764 // Map from r0 = or(r1, -2147483648) to r0 = setbit(r1, #31).
1765 def SETBIT_31 : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1766             "$dst = setbit($src1, #$src2)",
1767             []>;
1768
1769 def : Pat <(or (i32 IntRegs:$src1), -2147483648),
1770       (SETBIT_31 (i32 IntRegs:$src1), 31)>;
1771
1772 // togglebit.
1773 def TOGBIT : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1774             "$dst = setbit($src1, #$src2)",
1775             [(set (i32 IntRegs:$dst), (xor (i32 IntRegs:$src1),
1776                                           (shl 1, u5ImmPred:$src2)))]>;
1777
1778 // Map from r0 = xor(r1, -2147483648) to r0 = togglebit(r1, #31).
1779 def TOGBIT_31 : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1780             "$dst = togglebit($src1, #$src2)",
1781             []>;
1782
1783 def : Pat <(xor (i32 IntRegs:$src1), -2147483648),
1784       (TOGBIT_31 (i32 IntRegs:$src1), 31)>;
1785
1786 // Predicate transfer.
1787 let neverHasSideEffects = 1 in
1788 def TFR_RsPd : SInst<(outs IntRegs:$dst), (ins PredRegs:$src1),
1789                "$dst = $src1  /* Should almost never emit this. */",
1790                []>;
1791
1792 def TFR_PdRs : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1),
1793                "$dst = $src1  /* Should almost never emit this. */",
1794                [(set (i1 PredRegs:$dst), (trunc (i32 IntRegs:$src1)))]>;
1795 //===----------------------------------------------------------------------===//
1796 // STYPE/PRED -
1797 //===----------------------------------------------------------------------===//
1798
1799 //===----------------------------------------------------------------------===//
1800 // STYPE/SHIFT +
1801 //===----------------------------------------------------------------------===//
1802 // Shift by immediate.
1803 def ASR_ri : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1804              "$dst = asr($src1, #$src2)",
1805              [(set (i32 IntRegs:$dst), (sra (i32 IntRegs:$src1),
1806                                             u5ImmPred:$src2))]>;
1807
1808 def ASRd_ri : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2),
1809               "$dst = asr($src1, #$src2)",
1810               [(set (i64 DoubleRegs:$dst), (sra (i64 DoubleRegs:$src1),
1811                                                 u6ImmPred:$src2))]>;
1812
1813 def ASL : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1814           "$dst = asl($src1, #$src2)",
1815           [(set (i32 IntRegs:$dst), (shl (i32 IntRegs:$src1),
1816                                          u5ImmPred:$src2))]>;
1817
1818 def ASLd_ri : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2),
1819               "$dst = asl($src1, #$src2)",
1820               [(set (i64 DoubleRegs:$dst), (shl (i64 DoubleRegs:$src1),
1821                                                 u6ImmPred:$src2))]>;
1822
1823 def LSR_ri : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1824              "$dst = lsr($src1, #$src2)",
1825              [(set (i32 IntRegs:$dst), (srl (i32 IntRegs:$src1),
1826                                             u5ImmPred:$src2))]>;
1827
1828 def LSRd_ri : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2),
1829               "$dst = lsr($src1, #$src2)",
1830               [(set (i64 DoubleRegs:$dst), (srl (i64 DoubleRegs:$src1),
1831                                                 u6ImmPred:$src2))]>;
1832
1833 // Shift by immediate and add.
1834 let AddedComplexity = 100 in
1835 def ADDASL : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2,
1836                                              u3Imm:$src3),
1837              "$dst = addasl($src1, $src2, #$src3)",
1838              [(set (i32 IntRegs:$dst), (add (i32 IntRegs:$src1),
1839                                        (shl (i32 IntRegs:$src2),
1840                                             u3ImmPred:$src3)))]>;
1841
1842 // Shift by register.
1843 def ASL_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1844              "$dst = asl($src1, $src2)",
1845              [(set (i32 IntRegs:$dst), (shl (i32 IntRegs:$src1),
1846                                             (i32 IntRegs:$src2)))]>;
1847
1848 def ASR_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1849              "$dst = asr($src1, $src2)",
1850              [(set (i32 IntRegs:$dst), (sra (i32 IntRegs:$src1),
1851                                             (i32 IntRegs:$src2)))]>;
1852
1853 def LSL_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1854              "$dst = lsl($src1, $src2)",
1855              [(set (i32 IntRegs:$dst), (shl (i32 IntRegs:$src1),
1856                                             (i32 IntRegs:$src2)))]>;
1857
1858 def LSR_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1859              "$dst = lsr($src1, $src2)",
1860              [(set (i32 IntRegs:$dst), (srl (i32 IntRegs:$src1),
1861                                             (i32 IntRegs:$src2)))]>;
1862
1863 def ASLd : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, IntRegs:$src2),
1864            "$dst = asl($src1, $src2)",
1865            [(set (i64 DoubleRegs:$dst), (shl (i64 DoubleRegs:$src1),
1866                                              (i32 IntRegs:$src2)))]>;
1867
1868 def LSLd : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, IntRegs:$src2),
1869            "$dst = lsl($src1, $src2)",
1870            [(set (i64 DoubleRegs:$dst), (shl (i64 DoubleRegs:$src1),
1871                                              (i32 IntRegs:$src2)))]>;
1872
1873 def ASRd_rr : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
1874                                                  IntRegs:$src2),
1875               "$dst = asr($src1, $src2)",
1876               [(set (i64 DoubleRegs:$dst), (sra (i64 DoubleRegs:$src1),
1877                                                 (i32 IntRegs:$src2)))]>;
1878
1879 def LSRd_rr : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
1880                                                  IntRegs:$src2),
1881               "$dst = lsr($src1, $src2)",
1882               [(set (i64 DoubleRegs:$dst), (srl (i64 DoubleRegs:$src1),
1883                                                 (i32 IntRegs:$src2)))]>;
1884
1885 //===----------------------------------------------------------------------===//
1886 // STYPE/SHIFT -
1887 //===----------------------------------------------------------------------===//
1888
1889 //===----------------------------------------------------------------------===//
1890 // STYPE/VH +
1891 //===----------------------------------------------------------------------===//
1892 //===----------------------------------------------------------------------===//
1893 // STYPE/VH -
1894 //===----------------------------------------------------------------------===//
1895
1896 //===----------------------------------------------------------------------===//
1897 // STYPE/VW +
1898 //===----------------------------------------------------------------------===//
1899 //===----------------------------------------------------------------------===//
1900 // STYPE/VW -
1901 //===----------------------------------------------------------------------===//
1902
1903 //===----------------------------------------------------------------------===//
1904 // SYSTEM/SUPER +
1905 //===----------------------------------------------------------------------===//
1906
1907 //===----------------------------------------------------------------------===//
1908 // SYSTEM/USER +
1909 //===----------------------------------------------------------------------===//
1910 def SDHexagonBARRIER: SDTypeProfile<0, 0, []>;
1911 def HexagonBARRIER: SDNode<"HexagonISD::BARRIER", SDHexagonBARRIER,
1912                            [SDNPHasChain]>;
1913
1914 let hasSideEffects = 1, isSolo = 1 in
1915 def BARRIER : SYSInst<(outs), (ins),
1916                      "barrier",
1917                      [(HexagonBARRIER)]>;
1918
1919 //===----------------------------------------------------------------------===//
1920 // SYSTEM/SUPER -
1921 //===----------------------------------------------------------------------===//
1922
1923 // TFRI64 - assembly mapped.
1924 let isReMaterializable = 1 in
1925 def TFRI64 : ALU64_rr<(outs DoubleRegs:$dst), (ins s8Imm64:$src1),
1926              "$dst = #$src1",
1927              [(set (i64 DoubleRegs:$dst), s8Imm64Pred:$src1)]>;
1928
1929 // Pseudo instruction to encode a set of conditional transfers.
1930 // This instruction is used instead of a mux and trades-off codesize
1931 // for performance. We conduct this transformation optimistically in
1932 // the hope that these instructions get promoted to dot-new transfers.
1933 let AddedComplexity = 100, isPredicated = 1 in
1934 def TFR_condset_rr : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1,
1935                                                         IntRegs:$src2,
1936                                                         IntRegs:$src3),
1937                      "Error; should not emit",
1938                      [(set (i32 IntRegs:$dst),
1939                            (i32 (select (i1 PredRegs:$src1),
1940                                         (i32 IntRegs:$src2),
1941                                         (i32 IntRegs:$src3))))]>;
1942 let AddedComplexity = 100, isPredicated = 1 in
1943 def TFR_condset_ri : ALU32_rr<(outs IntRegs:$dst),
1944             (ins PredRegs:$src1, IntRegs:$src2, s12Imm:$src3),
1945             "Error; should not emit",
1946             [(set (i32 IntRegs:$dst),
1947              (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2),
1948                           s12ImmPred:$src3)))]>;
1949
1950 let AddedComplexity = 100, isPredicated = 1 in
1951 def TFR_condset_ir : ALU32_rr<(outs IntRegs:$dst),
1952             (ins PredRegs:$src1, s12Imm:$src2, IntRegs:$src3),
1953             "Error; should not emit",
1954             [(set (i32 IntRegs:$dst),
1955              (i32 (select (i1 PredRegs:$src1), s12ImmPred:$src2,
1956                           (i32 IntRegs:$src3))))]>;
1957
1958 let AddedComplexity = 100, isPredicated = 1 in
1959 def TFR_condset_ii : ALU32_rr<(outs IntRegs:$dst),
1960                               (ins PredRegs:$src1, s12Imm:$src2, s12Imm:$src3),
1961                      "Error; should not emit",
1962                      [(set (i32 IntRegs:$dst),
1963                            (i32 (select (i1 PredRegs:$src1), s12ImmPred:$src2,
1964                                         s12ImmPred:$src3)))]>;
1965
1966 // Generate frameindex addresses.
1967 let isReMaterializable = 1 in
1968 def TFR_FI : ALU32_ri<(outs IntRegs:$dst), (ins FrameIndex:$src1),
1969              "$dst = add($src1)",
1970              [(set (i32 IntRegs:$dst), ADDRri:$src1)]>;
1971
1972 //
1973 // CR - Type.
1974 //
1975 let neverHasSideEffects = 1, Defs = [SA0, LC0] in {
1976 def LOOP0_i : CRInst<(outs), (ins brtarget:$offset, u10Imm:$src2),
1977                       "loop0($offset, #$src2)",
1978                       []>;
1979 }
1980
1981 let neverHasSideEffects = 1, Defs = [SA0, LC0] in {
1982 def LOOP0_r : CRInst<(outs), (ins brtarget:$offset, IntRegs:$src2),
1983                       "loop0($offset, $src2)",
1984                       []>;
1985 }
1986
1987 let isBranch = 1, isTerminator = 1, neverHasSideEffects = 1,
1988     Defs = [PC, LC0], Uses = [SA0, LC0] in {
1989 def ENDLOOP0 : Endloop<(outs), (ins brtarget:$offset),
1990                        ":endloop0",
1991                        []>;
1992 }
1993
1994 // Support for generating global address.
1995 // Taken from X86InstrInfo.td.
1996 def SDTHexagonCONST32 : SDTypeProfile<1, 1, [
1997                                             SDTCisVT<0, i32>,
1998                                             SDTCisVT<1, i32>,
1999                                             SDTCisPtrTy<0>]>;
2000 def HexagonCONST32 : SDNode<"HexagonISD::CONST32",     SDTHexagonCONST32>;
2001 def HexagonCONST32_GP : SDNode<"HexagonISD::CONST32_GP",     SDTHexagonCONST32>;
2002
2003 // HI/LO Instructions
2004 let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
2005 def LO : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$global),
2006                   "$dst.l = #LO($global)",
2007                   []>;
2008
2009 let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
2010 def HI : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$global),
2011                   "$dst.h = #HI($global)",
2012                   []>;
2013
2014 let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
2015 def LOi : ALU32_ri<(outs IntRegs:$dst), (ins i32imm:$imm_value),
2016                   "$dst.l = #LO($imm_value)",
2017                   []>;
2018
2019
2020 let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
2021 def HIi : ALU32_ri<(outs IntRegs:$dst), (ins i32imm:$imm_value),
2022                   "$dst.h = #HI($imm_value)",
2023                   []>;
2024
2025 let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
2026 def LO_jt : ALU32_ri<(outs IntRegs:$dst), (ins jumptablebase:$jt),
2027                   "$dst.l = #LO($jt)",
2028                   []>;
2029
2030 let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
2031 def HI_jt : ALU32_ri<(outs IntRegs:$dst), (ins jumptablebase:$jt),
2032                   "$dst.h = #HI($jt)",
2033                   []>;
2034
2035
2036 let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
2037 def LO_label : ALU32_ri<(outs IntRegs:$dst), (ins bblabel:$label),
2038                   "$dst.l = #LO($label)",
2039                   []>;
2040
2041 let isReMaterializable = 1, isMoveImm = 1 , neverHasSideEffects = 1 in
2042 def HI_label : ALU32_ri<(outs IntRegs:$dst), (ins bblabel:$label),
2043                   "$dst.h = #HI($label)",
2044                   []>;
2045
2046 // This pattern is incorrect. When we add small data, we should change
2047 // this pattern to use memw(#foo).
2048 // This is for sdata.
2049 let isMoveImm = 1 in
2050 def CONST32 : LDInst<(outs IntRegs:$dst), (ins globaladdress:$global),
2051               "$dst = CONST32(#$global)",
2052               [(set (i32 IntRegs:$dst),
2053                     (load (HexagonCONST32 tglobaltlsaddr:$global)))]>;
2054
2055 // This is for non-sdata.
2056 let isReMaterializable = 1, isMoveImm = 1 in
2057 def CONST32_set : LDInst2<(outs IntRegs:$dst), (ins globaladdress:$global),
2058                   "$dst = CONST32(#$global)",
2059                   [(set (i32 IntRegs:$dst),
2060                         (HexagonCONST32 tglobaladdr:$global))]>;
2061
2062 let isReMaterializable = 1, isMoveImm = 1 in
2063 def CONST32_set_jt : LDInst2<(outs IntRegs:$dst), (ins jumptablebase:$jt),
2064                      "$dst = CONST32(#$jt)",
2065                      [(set (i32 IntRegs:$dst),
2066                            (HexagonCONST32 tjumptable:$jt))]>;
2067
2068 let isReMaterializable = 1, isMoveImm = 1 in
2069 def CONST32GP_set : LDInst2<(outs IntRegs:$dst), (ins globaladdress:$global),
2070                     "$dst = CONST32(#$global)",
2071                     [(set (i32 IntRegs:$dst),
2072                           (HexagonCONST32_GP tglobaladdr:$global))]>;
2073
2074 let isReMaterializable = 1, isMoveImm = 1 in
2075 def CONST32_Int_Real : LDInst2<(outs IntRegs:$dst), (ins i32imm:$global),
2076                        "$dst = CONST32(#$global)",
2077                        [(set (i32 IntRegs:$dst), imm:$global) ]>;
2078
2079 let isReMaterializable = 1, isMoveImm = 1 in
2080 def CONST32_Label : LDInst2<(outs IntRegs:$dst), (ins bblabel:$label),
2081                     "$dst = CONST32($label)",
2082                     [(set (i32 IntRegs:$dst), (HexagonCONST32 bbl:$label))]>;
2083
2084 let isReMaterializable = 1, isMoveImm = 1 in
2085 def CONST64_Int_Real : LDInst2<(outs DoubleRegs:$dst), (ins i64imm:$global),
2086                        "$dst = CONST64(#$global)",
2087                        [(set (i64 DoubleRegs:$dst), imm:$global) ]>;
2088
2089 def TFR_PdFalse : SInst<(outs PredRegs:$dst), (ins),
2090                   "$dst = xor($dst, $dst)",
2091                   [(set (i1 PredRegs:$dst), 0)]>;
2092
2093 def MPY_trsext : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
2094        "$dst = mpy($src1, $src2)",
2095        [(set (i32 IntRegs:$dst),
2096              (trunc (i64 (srl (i64 (mul (i64 (sext (i32 IntRegs:$src1))),
2097                                         (i64 (sext (i32 IntRegs:$src2))))),
2098                               (i32 32)))))]>;
2099
2100 // Pseudo instructions.
2101 def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
2102
2103 def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>,
2104                                         SDTCisVT<1, i32> ]>;
2105
2106 def callseq_end : SDNode<"ISD::CALLSEQ_END",   SDT_SPCallSeqEnd,
2107                   [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
2108
2109 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart,
2110                     [SDNPHasChain, SDNPOutGlue]>;
2111
2112 def SDT_SPCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
2113
2114 def call : SDNode<"HexagonISD::CALL", SDT_SPCall,
2115            [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;
2116
2117 // For tailcalls a HexagonTCRet SDNode has 3 SDNode Properties - a chain,
2118 // Optional Flag and Variable Arguments.
2119 // Its 1 Operand has pointer type.
2120 def HexagonTCRet    : SDNode<"HexagonISD::TC_RETURN", SDT_SPCall,
2121                      [SDNPHasChain,  SDNPOptInGlue, SDNPVariadic]>;
2122
2123 let Defs = [R29, R30], Uses = [R31, R30, R29] in {
2124  def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt),
2125                         "Should never be emitted",
2126                         [(callseq_start timm:$amt)]>;
2127 }
2128
2129 let Defs = [R29, R30, R31], Uses = [R29] in {
2130  def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
2131                       "Should never be emitted",
2132                       [(callseq_end timm:$amt1, timm:$amt2)]>;
2133 }
2134 // Call subroutine.
2135 let isCall = 1, neverHasSideEffects = 1,
2136   Defs = [D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10,
2137           R22, R23, R28, R31, P0, P1, P2, P3, LC0, LC1, SA0, SA1] in {
2138   def CALL : JInst<(outs), (ins calltarget:$dst),
2139              "call $dst", []>;
2140 }
2141
2142 // Call subroutine from register.
2143 let isCall = 1, neverHasSideEffects = 1,
2144   Defs = [D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10,
2145           R22, R23, R28, R31, P0, P1, P2, P3, LC0, LC1, SA0, SA1] in {
2146   def CALLR : JRInst<(outs), (ins IntRegs:$dst),
2147               "callr $dst",
2148               []>;
2149  }
2150
2151 // Tail Calls.
2152 let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1 in {
2153   def TCRETURNtg : JInst<(outs), (ins calltarget:$dst),
2154              "jump $dst // TAILCALL", []>;
2155 }
2156 let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1 in {
2157   def TCRETURNtext : JInst<(outs), (ins calltarget:$dst),
2158              "jump $dst // TAILCALL", []>;
2159 }
2160
2161 let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1 in {
2162   def TCRETURNR : JInst<(outs), (ins IntRegs:$dst),
2163              "jumpr $dst // TAILCALL", []>;
2164 }
2165 // Map call instruction.
2166 def : Pat<(call (i32 IntRegs:$dst)),
2167       (CALLR (i32 IntRegs:$dst))>, Requires<[HasV2TOnly]>;
2168 def : Pat<(call tglobaladdr:$dst),
2169       (CALL tglobaladdr:$dst)>, Requires<[HasV2TOnly]>;
2170 def : Pat<(call texternalsym:$dst),
2171       (CALL texternalsym:$dst)>, Requires<[HasV2TOnly]>;
2172 //Tail calls.
2173 def : Pat<(HexagonTCRet tglobaladdr:$dst),
2174       (TCRETURNtg tglobaladdr:$dst)>;
2175 def : Pat<(HexagonTCRet texternalsym:$dst),
2176       (TCRETURNtext texternalsym:$dst)>;
2177 def : Pat<(HexagonTCRet (i32 IntRegs:$dst)),
2178       (TCRETURNR (i32 IntRegs:$dst))>;
2179
2180 // Atomic load and store support
2181 // 8 bit atomic load
2182 def : Pat<(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)),
2183           (i32 (LDub_GP tglobaladdr:$global))>,
2184             Requires<[NoV4T]>;
2185
2186 def : Pat<(atomic_load_8 (add (HexagonCONST32_GP tglobaladdr:$global),
2187                               u16ImmPred:$offset)),
2188           (i32 (LDriub_GP tglobaladdr:$global, u16ImmPred:$offset))>,
2189             Requires<[NoV4T]>;
2190
2191 def : Pat<(atomic_load_8 ADDRriS11_0:$src1),
2192           (i32 (LDriub ADDRriS11_0:$src1))>;
2193
2194 def : Pat<(atomic_load_8 (add (i32 IntRegs:$src1), s11_0ImmPred:$offset)),
2195           (i32 (LDriub_indexed (i32 IntRegs:$src1), s11_0ImmPred:$offset))>;
2196
2197
2198
2199 // 16 bit atomic load
2200 def : Pat<(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)),
2201           (i32 (LDuh_GP tglobaladdr:$global))>,
2202             Requires<[NoV4T]>;
2203
2204 def : Pat<(atomic_load_16 (add (HexagonCONST32_GP tglobaladdr:$global),
2205                                u16ImmPred:$offset)),
2206           (i32 (LDriuh_GP tglobaladdr:$global, u16ImmPred:$offset))>,
2207             Requires<[NoV4T]>;
2208
2209 def : Pat<(atomic_load_16 ADDRriS11_1:$src1),
2210           (i32 (LDriuh ADDRriS11_1:$src1))>;
2211
2212 def : Pat<(atomic_load_16 (add (i32 IntRegs:$src1), s11_1ImmPred:$offset)),
2213           (i32 (LDriuh_indexed (i32 IntRegs:$src1), s11_1ImmPred:$offset))>;
2214
2215
2216
2217 // 32 bit atomic load
2218 def : Pat<(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)),
2219           (i32 (LDw_GP tglobaladdr:$global))>,
2220             Requires<[NoV4T]>;
2221
2222 def : Pat<(atomic_load_32 (add (HexagonCONST32_GP tglobaladdr:$global),
2223                                u16ImmPred:$offset)),
2224           (i32 (LDriw_GP tglobaladdr:$global, u16ImmPred:$offset))>,
2225             Requires<[NoV4T]>;
2226
2227 def : Pat<(atomic_load_32 ADDRriS11_2:$src1),
2228           (i32 (LDriw ADDRriS11_2:$src1))>;
2229
2230 def : Pat<(atomic_load_32 (add (i32 IntRegs:$src1), s11_2ImmPred:$offset)),
2231           (i32 (LDriw_indexed (i32 IntRegs:$src1), s11_2ImmPred:$offset))>;
2232
2233
2234 // 64 bit atomic load
2235 def : Pat<(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
2236           (i64 (LDd_GP tglobaladdr:$global))>,
2237             Requires<[NoV4T]>;
2238
2239 def : Pat<(atomic_load_64 (add (HexagonCONST32_GP tglobaladdr:$global),
2240                                u16ImmPred:$offset)),
2241           (i64 (LDrid_GP tglobaladdr:$global, u16ImmPred:$offset))>,
2242           Requires<[NoV4T]>;
2243
2244 def : Pat<(atomic_load_64 ADDRriS11_3:$src1),
2245           (i64 (LDrid ADDRriS11_3:$src1))>;
2246
2247 def : Pat<(atomic_load_64 (add (i32 IntRegs:$src1), s11_3ImmPred:$offset)),
2248           (i64 (LDrid_indexed (i32 IntRegs:$src1), s11_3ImmPred:$offset))>;
2249
2250
2251 // 64 bit atomic store
2252 def : Pat<(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
2253                            (i64 DoubleRegs:$src1)),
2254           (STd_GP tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
2255           Requires<[NoV4T]>;
2256
2257 def : Pat<(atomic_store_64 (add (HexagonCONST32_GP tglobaladdr:$global),
2258                                 u16ImmPred:$offset),
2259                            (i64 DoubleRegs:$src1)),
2260           (STrid_GP tglobaladdr:$global, u16ImmPred:$offset,
2261                     (i64 DoubleRegs:$src1))>, Requires<[NoV4T]>;
2262
2263 // 8 bit atomic store
2264 def : Pat<(atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
2265                           (i32 IntRegs:$src1)),
2266           (STb_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
2267           Requires<[NoV4T]>;
2268
2269 def : Pat<(atomic_store_8 (add (HexagonCONST32_GP tglobaladdr:$global),
2270                                u16ImmPred:$offset),
2271                           (i32 IntRegs:$src1)),
2272           (STrib_GP tglobaladdr:$global, u16ImmPred:$offset,
2273                     (i32 IntRegs:$src1))>, Requires<[NoV4T]>;
2274
2275 def : Pat<(atomic_store_8 ADDRriS11_0:$src2, (i32 IntRegs:$src1)),
2276           (STrib ADDRriS11_0:$src2, (i32 IntRegs:$src1))>;
2277
2278 def : Pat<(atomic_store_8 (add (i32 IntRegs:$src2), s11_0ImmPred:$offset),
2279                           (i32 IntRegs:$src1)),
2280           (STrib_indexed (i32 IntRegs:$src2), s11_0ImmPred:$offset,
2281                          (i32 IntRegs:$src1))>;
2282
2283
2284 // 16 bit atomic store
2285 def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
2286                            (i32 IntRegs:$src1)),
2287           (STh_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
2288           Requires<[NoV4T]>;
2289
2290 def : Pat<(atomic_store_16 (add (HexagonCONST32_GP tglobaladdr:$global),
2291                                 u16ImmPred:$offset),
2292                            (i32 IntRegs:$src1)),
2293           (STrih_GP tglobaladdr:$global, u16ImmPred:$offset,
2294                     (i32 IntRegs:$src1))>, Requires<[NoV4T]>;
2295
2296 def : Pat<(atomic_store_16 ADDRriS11_1:$src2, (i32 IntRegs:$src1)),
2297           (STrih ADDRriS11_1:$src2, (i32 IntRegs:$src1))>;
2298
2299 def : Pat<(atomic_store_16 (i32 IntRegs:$src1),
2300                           (add (i32 IntRegs:$src2), s11_1ImmPred:$offset)),
2301           (STrih_indexed (i32 IntRegs:$src2), s11_1ImmPred:$offset,
2302                          (i32 IntRegs:$src1))>;
2303
2304
2305 // 32 bit atomic store
2306 def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
2307                            (i32 IntRegs:$src1)),
2308           (STw_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
2309           Requires<[NoV4T]>;
2310
2311 def : Pat<(atomic_store_32 (add (HexagonCONST32_GP tglobaladdr:$global),
2312                                 u16ImmPred:$offset),
2313                            (i32 IntRegs:$src1)),
2314           (STriw_GP tglobaladdr:$global, u16ImmPred:$offset,
2315                                          (i32 IntRegs:$src1))>,
2316             Requires<[NoV4T]>;
2317
2318 def : Pat<(atomic_store_32 ADDRriS11_2:$src2, (i32 IntRegs:$src1)),
2319           (STriw ADDRriS11_2:$src2, (i32 IntRegs:$src1))>;
2320
2321 def : Pat<(atomic_store_32 (add (i32 IntRegs:$src2), s11_2ImmPred:$offset),
2322                            (i32 IntRegs:$src1)),
2323           (STriw_indexed (i32 IntRegs:$src2), s11_2ImmPred:$offset,
2324                          (i32 IntRegs:$src1))>;
2325
2326
2327
2328
2329 def : Pat<(atomic_store_64 ADDRriS11_3:$src2, (i64 DoubleRegs:$src1)),
2330           (STrid ADDRriS11_3:$src2, (i64 DoubleRegs:$src1))>;
2331
2332 def : Pat<(atomic_store_64 (add (i32 IntRegs:$src2), s11_3ImmPred:$offset),
2333                            (i64 DoubleRegs:$src1)),
2334           (STrid_indexed (i32 IntRegs:$src2), s11_3ImmPred:$offset,
2335                          (i64 DoubleRegs:$src1))>;
2336
2337 // Map from r0 = and(r1, 65535) to r0 = zxth(r1)
2338 def : Pat <(and (i32 IntRegs:$src1), 65535),
2339       (ZXTH (i32 IntRegs:$src1))>;
2340
2341 // Map from r0 = and(r1, 255) to r0 = zxtb(r1).
2342 def : Pat <(and (i32 IntRegs:$src1), 255),
2343       (ZXTB (i32 IntRegs:$src1))>;
2344
2345 // Map Add(p1, true) to p1 = not(p1).
2346 //     Add(p1, false) should never be produced,
2347 //     if it does, it got to be mapped to NOOP.
2348 def : Pat <(add (i1 PredRegs:$src1), -1),
2349       (NOT_p (i1 PredRegs:$src1))>;
2350
2351 // Map from p0 = setlt(r0, r1) r2 = mux(p0, r3, r4) =>
2352 //   p0 = cmp.lt(r0, r1), r0 = mux(p0, r2, r1).
2353 def : Pat <(select (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2354                    (i32 IntRegs:$src3),
2355                    (i32 IntRegs:$src4)),
2356       (i32 (TFR_condset_rr (CMPLTrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
2357                            (i32 IntRegs:$src4), (i32 IntRegs:$src3)))>,
2358       Requires<[HasV2TOnly]>;
2359
2360 // Map from p0 = pnot(p0); r0 = mux(p0, #i, #j) => r0 = mux(p0, #j, #i).
2361 def : Pat <(select (not (i1 PredRegs:$src1)), s8ImmPred:$src2, s8ImmPred:$src3),
2362       (i32 (TFR_condset_ii (i1 PredRegs:$src1), s8ImmPred:$src3,
2363                            s8ImmPred:$src2))>;
2364
2365 // Map from p0 = pnot(p0); r0 = select(p0, #i, r1)
2366 // => r0 = TFR_condset_ri(p0, r1, #i)
2367 def : Pat <(select (not (i1 PredRegs:$src1)), s12ImmPred:$src2,
2368                    (i32 IntRegs:$src3)),
2369       (i32 (TFR_condset_ri (i1 PredRegs:$src1), (i32 IntRegs:$src3),
2370                            s12ImmPred:$src2))>;
2371
2372 // Map from p0 = pnot(p0); r0 = mux(p0, r1, #i)
2373 // => r0 = TFR_condset_ir(p0, #i, r1)
2374 def : Pat <(select (not PredRegs:$src1), IntRegs:$src2, s12ImmPred:$src3),
2375       (i32 (TFR_condset_ir (i1 PredRegs:$src1), s12ImmPred:$src3,
2376                            (i32 IntRegs:$src2)))>;
2377
2378 // Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump.
2379 def : Pat <(brcond (not PredRegs:$src1), bb:$offset),
2380       (JMP_cNot (i1 PredRegs:$src1), bb:$offset)>;
2381
2382 // Map from p2 = pnot(p2); p1 = and(p0, p2) => p1 = and(p0, !p2).
2383 def : Pat <(and PredRegs:$src1, (not PredRegs:$src2)),
2384       (i1 (AND_pnotp (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>;
2385
2386 // Map from store(globaladdress + x) -> memd(#foo + x).
2387 let AddedComplexity = 100 in
2388 def : Pat <(store (i64 DoubleRegs:$src1),
2389                   (add (HexagonCONST32_GP tglobaladdr:$global),
2390                        u16ImmPred:$offset)),
2391       (STrid_GP tglobaladdr:$global, u16ImmPred:$offset,
2392                 (i64 DoubleRegs:$src1))>, Requires<[NoV4T]>;
2393
2394 // Map from store(globaladdress) -> memd(#foo).
2395 let AddedComplexity = 100 in
2396 def : Pat <(store (i64 DoubleRegs:$src1),
2397                   (HexagonCONST32_GP tglobaladdr:$global)),
2398       (STd_GP tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
2399       Requires<[NoV4T]>;
2400
2401 // Map from store(globaladdress + x) -> memw(#foo + x).
2402 let AddedComplexity = 100 in
2403 def : Pat <(store (i32 IntRegs:$src1),
2404               (add (HexagonCONST32_GP tglobaladdr:$global),
2405                                       u16ImmPred:$offset)),
2406       (STriw_GP tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>,
2407       Requires<[NoV4T]>;
2408
2409 // Map from store(globaladdress) -> memw(#foo + 0).
2410 let AddedComplexity = 100 in
2411 def : Pat <(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
2412       (STriw_GP tglobaladdr:$global, 0, (i32 IntRegs:$src1))>;
2413
2414 // Map from store(globaladdress) -> memw(#foo).
2415 let AddedComplexity = 100 in
2416 def : Pat <(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
2417       (STriw_GP tglobaladdr:$global, 0, (i32 IntRegs:$src1))>,
2418       Requires<[NoV4T]>;
2419
2420 // Map from store(globaladdress + x) -> memh(#foo + x).
2421 let AddedComplexity = 100 in
2422 def : Pat <(truncstorei16 (i32 IntRegs:$src1),
2423                           (add (HexagonCONST32_GP tglobaladdr:$global),
2424                                u16ImmPred:$offset)),
2425       (STrih_GP tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>,
2426       Requires<[NoV4T]>;
2427
2428 // Map from store(globaladdress) -> memh(#foo).
2429 let AddedComplexity = 100 in
2430 def : Pat <(truncstorei16 (i32 IntRegs:$src1),
2431                           (HexagonCONST32_GP tglobaladdr:$global)),
2432       (STh_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
2433       Requires<[NoV4T]>;
2434
2435 // Map from store(globaladdress + x) -> memb(#foo + x).
2436 let AddedComplexity = 100 in
2437 def : Pat <(truncstorei8 (i32 IntRegs:$src1),
2438                          (add (HexagonCONST32_GP tglobaladdr:$global),
2439                               u16ImmPred:$offset)),
2440       (STrib_GP tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>,
2441       Requires<[NoV4T]>;
2442
2443 // Map from store(globaladdress) -> memb(#foo).
2444 let AddedComplexity = 100 in
2445 def : Pat <(truncstorei8 (i32 IntRegs:$src1),
2446                          (HexagonCONST32_GP tglobaladdr:$global)),
2447       (STb_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
2448       Requires<[NoV4T]>;
2449
2450 // Map from load(globaladdress + x) -> memw(#foo + x).
2451 let AddedComplexity = 100 in
2452 def : Pat <(i32 (load (add (HexagonCONST32_GP tglobaladdr:$global),
2453                       u16ImmPred:$offset))),
2454       (i32 (LDriw_GP tglobaladdr:$global, u16ImmPred:$offset))>,
2455       Requires<[NoV4T]>;
2456
2457 // Map from load(globaladdress) -> memw(#foo).
2458 let AddedComplexity = 100 in
2459 def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
2460       (i32 (LDw_GP tglobaladdr:$global))>,
2461       Requires<[NoV4T]>;
2462
2463 // Map from load(globaladdress + x) -> memd(#foo + x).
2464 let AddedComplexity = 100 in
2465 def : Pat <(i64 (load (add (HexagonCONST32_GP tglobaladdr:$global),
2466                            u16ImmPred:$offset))),
2467       (i64 (LDrid_GP tglobaladdr:$global, u16ImmPred:$offset))>,
2468       Requires<[NoV4T]>;
2469
2470 // Map from load(globaladdress) -> memw(#foo + 0).
2471 let AddedComplexity = 100 in
2472 def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))),
2473       (i64 (LDd_GP tglobaladdr:$global))>,
2474       Requires<[NoV4T]>;
2475
2476 // Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd.
2477 let AddedComplexity = 100 in
2478 def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))),
2479       (i1 (TFR_PdRs (i32 (LDb_GP tglobaladdr:$global))))>,
2480       Requires<[NoV4T]>;
2481
2482 // Map from load(globaladdress + x) -> memh(#foo + x).
2483 let AddedComplexity = 100 in
2484 def : Pat <(i32 (extloadi16 (add (HexagonCONST32_GP tglobaladdr:$global),
2485                             u16ImmPred:$offset))),
2486       (i32 (LDrih_GP tglobaladdr:$global, u16ImmPred:$offset))>,
2487       Requires<[NoV4T]>;
2488
2489 // Map from load(globaladdress + x) -> memh(#foo + x).
2490 let AddedComplexity = 100 in
2491 def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
2492       (i32 (LDrih_GP tglobaladdr:$global, 0))>,
2493       Requires<[NoV4T]>;
2494
2495 // Map from load(globaladdress + x) -> memuh(#foo + x).
2496 let AddedComplexity = 100 in
2497 def : Pat <(i32 (zextloadi16 (add (HexagonCONST32_GP tglobaladdr:$global),
2498                              u16ImmPred:$offset))),
2499       (i32 (LDriuh_GP tglobaladdr:$global, u16ImmPred:$offset))>,
2500       Requires<[NoV4T]>;
2501
2502 // Map from load(globaladdress) -> memuh(#foo).
2503 let AddedComplexity = 100 in
2504 def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
2505       (i32 (LDriuh_GP tglobaladdr:$global, 0))>,
2506       Requires<[NoV4T]>;
2507
2508 // Map from load(globaladdress) -> memh(#foo).
2509 let AddedComplexity = 100 in
2510 def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
2511       (i32 (LDh_GP tglobaladdr:$global))>,
2512       Requires<[NoV4T]>;
2513
2514 // Map from load(globaladdress) -> memuh(#foo).
2515 let AddedComplexity = 100 in
2516 def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
2517       (i32 (LDuh_GP tglobaladdr:$global))>,
2518       Requires<[NoV4T]>;
2519
2520 // Map from load(globaladdress + x) -> memb(#foo + x).
2521 let AddedComplexity = 100 in
2522 def : Pat <(i32 (extloadi8 (add (HexagonCONST32_GP tglobaladdr:$global),
2523                            u16ImmPred:$offset))),
2524       (i32 (LDrib_GP tglobaladdr:$global, u16ImmPred:$offset))>,
2525       Requires<[NoV4T]>;
2526
2527 // Map from load(globaladdress + x) -> memb(#foo + x).
2528 let AddedComplexity = 100 in
2529 def : Pat <(i32 (sextloadi8 (add (HexagonCONST32_GP tglobaladdr:$global),
2530                             u16ImmPred:$offset))),
2531       (i32 (LDrib_GP tglobaladdr:$global, u16ImmPred:$offset))>,
2532       Requires<[NoV4T]>;
2533
2534 // Map from load(globaladdress + x) -> memub(#foo + x).
2535 let AddedComplexity = 100 in
2536 def : Pat <(i32 (zextloadi8 (add (HexagonCONST32_GP tglobaladdr:$global),
2537                             u16ImmPred:$offset))),
2538       (i32 (LDriub_GP tglobaladdr:$global, u16ImmPred:$offset))>,
2539       Requires<[NoV4T]>;
2540
2541 // Map from load(globaladdress) -> memb(#foo).
2542 let AddedComplexity = 100 in
2543 def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
2544       (i32 (LDb_GP tglobaladdr:$global))>,
2545       Requires<[NoV4T]>;
2546
2547 // Map from load(globaladdress) -> memb(#foo).
2548 let AddedComplexity = 100 in
2549 def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
2550       (i32 (LDb_GP tglobaladdr:$global))>,
2551       Requires<[NoV4T]>;
2552
2553 // Map from load(globaladdress) -> memub(#foo).
2554 let AddedComplexity = 100 in
2555 def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
2556       (i32 (LDub_GP tglobaladdr:$global))>,
2557       Requires<[NoV4T]>;
2558
2559 // When the Interprocedural Global Variable optimizer realizes that a
2560 // certain global variable takes only two constant values, it shrinks the
2561 // global to a boolean. Catch those loads here in the following 3 patterns.
2562 let AddedComplexity = 100 in
2563 def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
2564       (i32 (LDb_GP tglobaladdr:$global))>,
2565       Requires<[NoV4T]>;
2566
2567 let AddedComplexity = 100 in
2568 def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
2569       (i32 (LDb_GP tglobaladdr:$global))>,
2570       Requires<[NoV4T]>;
2571
2572 let AddedComplexity = 100 in
2573 def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
2574       (i32 (LDub_GP tglobaladdr:$global))>,
2575       Requires<[NoV4T]>;
2576
2577 // Map from i1 loads to 32 bits. This assumes that the i1* is byte aligned.
2578 def : Pat <(i32 (zextloadi1 ADDRriS11_0:$addr)),
2579       (i32 (AND_rr (i32 (LDrib ADDRriS11_0:$addr)), (TFRI 0x1)))>;
2580
2581 // Map from Rdd = sign_extend_inreg(Rss, i32) -> Rdd = SXTW(Rss.lo).
2582 def : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i32)),
2583       (i64 (SXTW (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_loreg))))>;
2584
2585 // Map from Rdd = sign_extend_inreg(Rss, i16) -> Rdd = SXTW(SXTH(Rss.lo)).
2586 def : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i16)),
2587       (i64 (SXTW (i32 (SXTH (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
2588                                                  subreg_loreg))))))>;
2589
2590 // Map from Rdd = sign_extend_inreg(Rss, i8) -> Rdd = SXTW(SXTB(Rss.lo)).
2591 def : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i8)),
2592       (i64 (SXTW (i32 (SXTB (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
2593                                                  subreg_loreg))))))>;
2594
2595 // We want to prevent emitting pnot's as much as possible.
2596 // Map brcond with an unsupported setcc to a JMP_cNot.
2597 def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2598                         bb:$offset),
2599       (JMP_cNot (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
2600                 bb:$offset)>;
2601
2602 def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), s10ImmPred:$src2)),
2603                         bb:$offset),
2604       (JMP_cNot (CMPEQri (i32 IntRegs:$src1), s10ImmPred:$src2), bb:$offset)>;
2605
2606 def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 -1))), bb:$offset),
2607       (JMP_cNot (i1 PredRegs:$src1), bb:$offset)>;
2608
2609 def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 0))), bb:$offset),
2610       (JMP_c (i1 PredRegs:$src1), bb:$offset)>;
2611
2612 def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), s8ImmPred:$src2)),
2613                         bb:$offset),
2614       (JMP_cNot (CMPGEri (i32 IntRegs:$src1), s8ImmPred:$src2), bb:$offset)>;
2615
2616 def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2617                         bb:$offset),
2618       (JMP_c (CMPLTrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)), bb:$offset)>;
2619
2620 def : Pat <(brcond (i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2621                    bb:$offset),
2622       (JMP_cNot (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)),
2623                    bb:$offset)>;
2624
2625 def : Pat <(brcond (i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2626                         bb:$offset),
2627       (JMP_cNot (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
2628                 bb:$offset)>;
2629
2630 def : Pat <(brcond (i1 (setule (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2631                    bb:$offset),
2632       (JMP_cNot (CMPGTU64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
2633                 bb:$offset)>;
2634
2635 // Map from a 64-bit select to an emulated 64-bit mux.
2636 // Hexagon does not support 64-bit MUXes; so emulate with combines.
2637 def : Pat <(select (i1 PredRegs:$src1), (i64 DoubleRegs:$src2),
2638                    (i64 DoubleRegs:$src3)),
2639       (i64 (COMBINE_rr (i32 (MUX_rr (i1 PredRegs:$src1),
2640                                     (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2),
2641                                                          subreg_hireg)),
2642                                     (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src3),
2643                                                          subreg_hireg)))),
2644                        (i32 (MUX_rr (i1 PredRegs:$src1),
2645                                     (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2),
2646                                                          subreg_loreg)),
2647                                     (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src3),
2648                                                          subreg_loreg))))))>;
2649
2650 // Map from a 1-bit select to logical ops.
2651 // From LegalizeDAG.cpp: (B1 ? B2 : B3) <=> (B1 & B2)|(!B1&B3).
2652 def : Pat <(select (i1 PredRegs:$src1), (i1 PredRegs:$src2),
2653                    (i1 PredRegs:$src3)),
2654       (OR_pp (AND_pp (i1 PredRegs:$src1), (i1 PredRegs:$src2)),
2655              (AND_pp (NOT_p (i1 PredRegs:$src1)), (i1 PredRegs:$src3)))>;
2656
2657 // Map Pd = load(addr) -> Rs = load(addr); Pd = Rs.
2658 def : Pat<(i1 (load ADDRriS11_2:$addr)),
2659       (i1 (TFR_PdRs (i32 (LDrib ADDRriS11_2:$addr))))>;
2660
2661 // Map for truncating from 64 immediates to 32 bit immediates.
2662 def : Pat<(i32 (trunc (i64 DoubleRegs:$src))),
2663       (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src), subreg_loreg))>;
2664
2665 // Map for truncating from i64 immediates to i1 bit immediates.
2666 def :  Pat<(i1 (trunc (i64 DoubleRegs:$src))),
2667        (i1 (TFR_PdRs (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
2668                                           subreg_loreg))))>;
2669
2670 // Map memb(Rs) = Rdd -> memb(Rs) = Rt.
2671 def : Pat<(truncstorei8 (i64 DoubleRegs:$src), ADDRriS11_0:$addr),
2672       (STrib ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
2673                                                      subreg_loreg)))>;
2674
2675 // Map memh(Rs) = Rdd -> memh(Rs) = Rt.
2676 def : Pat<(truncstorei16 (i64 DoubleRegs:$src), ADDRriS11_0:$addr),
2677       (STrih ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
2678                                                      subreg_loreg)))>;
2679 // Map memw(Rs) = Rdd -> memw(Rs) = Rt
2680 def : Pat<(truncstorei32 (i64  DoubleRegs:$src), ADDRriS11_0:$addr),
2681       (STriw ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
2682                                                      subreg_loreg)))>;
2683
2684 // Map memw(Rs) = Rdd -> memw(Rs) = Rt.
2685 def : Pat<(truncstorei32 (i64 DoubleRegs:$src), ADDRriS11_0:$addr),
2686       (STriw ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
2687                                                      subreg_loreg)))>;
2688
2689 // Map from i1 = constant<-1>; memw(addr) = i1 -> r0 = 1; memw(addr) = r0.
2690 def : Pat<(store (i1 -1), ADDRriS11_2:$addr),
2691       (STrib ADDRriS11_2:$addr, (TFRI 1))>;
2692
2693 let AddedComplexity = 100 in
2694 // Map from i1 = constant<-1>; memw(CONST32(#foo)) = i1 -> r0 = 1;
2695 // memw(#foo) = r0
2696 def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
2697       (STb_GP tglobaladdr:$global, (TFRI 1))>,
2698       Requires<[NoV4T]>;
2699
2700 // Map from i1 = constant<-1>; store i1 -> r0 = 1; store r0.
2701 def : Pat<(store (i1 -1), ADDRriS11_2:$addr),
2702       (STrib ADDRriS11_2:$addr, (TFRI 1))>;
2703
2704 // Map from memb(Rs) = Pd -> Rt = mux(Pd, #0, #1); store Rt.
2705 def : Pat<(store (i1 PredRegs:$src1), ADDRriS11_2:$addr),
2706       (STrib ADDRriS11_2:$addr, (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0)) )>;
2707
2708 // Map Rdd = anyext(Rs) -> Rdd = sxtw(Rs).
2709 // Hexagon_TODO: We can probably use combine but that will cost 2 instructions.
2710 // Better way to do this?
2711 def : Pat<(i64 (anyext (i32 IntRegs:$src1))),
2712       (i64 (SXTW (i32 IntRegs:$src1)))>;
2713
2714 // Map cmple -> cmpgt.
2715 // rs <= rt -> !(rs > rt).
2716 def : Pat<(i1 (setle (i32 IntRegs:$src1), s10ImmPred:$src2)),
2717       (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), s10ImmPred:$src2)))>;
2718
2719 // rs <= rt -> !(rs > rt).
2720 def : Pat<(i1 (setle (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2721       (i1 (NOT_p (CMPGTrr (i32 IntRegs:$src1), (i32 IntRegs:$src2))))>;
2722
2723 // Rss <= Rtt -> !(Rss > Rtt).
2724 def : Pat<(i1 (setle (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2725       (i1 (NOT_p (CMPGT64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))))>;
2726
2727 // Map cmpne -> cmpeq.
2728 // Hexagon_TODO: We should improve on this.
2729 // rs != rt -> !(rs == rt).
2730 def : Pat <(i1 (setne (i32 IntRegs:$src1), s10ImmPred:$src2)),
2731       (i1 (NOT_p(i1 (CMPEQri (i32 IntRegs:$src1), s10ImmPred:$src2))))>;
2732
2733 // Map cmpne(Rs) -> !cmpeqe(Rs).
2734 // rs != rt -> !(rs == rt).
2735 def : Pat <(i1 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2736       (i1 (NOT_p (i1 (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)))))>;
2737
2738 // Convert setne back to xor for hexagon since we compute w/ pred registers.
2739 def : Pat <(i1 (setne (i1 PredRegs:$src1), (i1 PredRegs:$src2))),
2740       (i1 (XOR_pp (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>;
2741
2742 // Map cmpne(Rss) -> !cmpew(Rss).
2743 // rs != rt -> !(rs == rt).
2744 def : Pat <(i1 (setne (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2745       (i1 (NOT_p (i1 (CMPEHexagon4rr (i64 DoubleRegs:$src1),
2746                                      (i64 DoubleRegs:$src2)))))>;
2747
2748 // Map cmpge(Rs, Rt) -> !(cmpgt(Rs, Rt).
2749 // rs >= rt -> !(rt > rs).
2750 def : Pat <(i1 (setge (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2751       (i1 (NOT_p (i1 (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))))>;
2752
2753 def : Pat <(i1 (setge (i32 IntRegs:$src1), s8ImmPred:$src2)),
2754       (i1 (CMPGEri (i32 IntRegs:$src1), s8ImmPred:$src2))>;
2755
2756 // Map cmpge(Rss, Rtt) -> !cmpgt(Rtt, Rss).
2757 // rss >= rtt -> !(rtt > rss).
2758 def : Pat <(i1 (setge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2759       (i1 (NOT_p (i1 (CMPGT64rr (i64 DoubleRegs:$src2),
2760                                 (i64 DoubleRegs:$src1)))))>;
2761
2762 // Map cmplt(Rs, Imm) -> !cmpge(Rs, Imm).
2763 // rs < rt -> !(rs >= rt).
2764 def : Pat <(i1 (setlt (i32 IntRegs:$src1), s8ImmPred:$src2)),
2765       (i1 (NOT_p (CMPGEri (i32 IntRegs:$src1), s8ImmPred:$src2)))>;
2766
2767 // Map cmplt(Rs, Rt) -> cmpgt(Rt, Rs).
2768 // rs < rt -> rt > rs.
2769 // We can let assembler map it, or we can do in the compiler itself.
2770 def : Pat <(i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2771       (i1 (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))>;
2772
2773 // Map cmplt(Rss, Rtt) -> cmpgt(Rtt, Rss).
2774 // rss < rtt -> (rtt > rss).
2775 def : Pat <(i1 (setlt (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2776       (i1 (CMPGT64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)))>;
2777
2778 // Map from cmpltu(Rs, Rd) -> cmpgtu(Rd, Rs)
2779 // rs < rt -> rt > rs.
2780 // We can let assembler map it, or we can do in the compiler itself.
2781 def : Pat <(i1 (setult (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2782       (i1 (CMPGTUrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))>;
2783
2784 // Map from cmpltu(Rss, Rdd) -> cmpgtu(Rdd, Rss).
2785 // rs < rt -> rt > rs.
2786 def : Pat <(i1 (setult (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2787       (i1 (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)))>;
2788
2789 // Generate cmpgeu(Rs, #u8)
2790 def : Pat <(i1 (setuge (i32 IntRegs:$src1), u8ImmPred:$src2)),
2791       (i1 (CMPGEUri (i32 IntRegs:$src1), u8ImmPred:$src2))>;
2792
2793 // Generate cmpgtu(Rs, #u9)
2794 def : Pat <(i1 (setugt (i32 IntRegs:$src1), u9ImmPred:$src2)),
2795       (i1 (CMPGTUri (i32 IntRegs:$src1), u9ImmPred:$src2))>;
2796
2797 // Map from Rs >= Rt -> !(Rt > Rs).
2798 // rs >= rt -> !(rt > rs).
2799 def : Pat <(i1 (setuge (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2800       (i1 (NOT_p (CMPGTUrr (i32 IntRegs:$src2), (i32 IntRegs:$src1))))>;
2801
2802 // Map from Rs >= Rt -> !(Rt > Rs).
2803 // rs >= rt -> !(rt > rs).
2804 def : Pat <(i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2805       (i1 (NOT_p (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1))))>;
2806
2807 // Map from cmpleu(Rs, Rs) -> !cmpgtu(Rs, Rs).
2808 // Map from (Rs <= Rt) -> !(Rs > Rt).
2809 def : Pat <(i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2810       (i1 (NOT_p (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2))))>;
2811
2812 // Map from cmpleu(Rss, Rtt) -> !cmpgtu(Rss, Rtt-1).
2813 // Map from (Rs <= Rt) -> !(Rs > Rt).
2814 def : Pat <(i1 (setule (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2815       (i1 (NOT_p (CMPGTU64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))))>;
2816
2817 // Sign extends.
2818 // i1 -> i32
2819 def : Pat <(i32 (sext (i1 PredRegs:$src1))),
2820       (i32 (MUX_ii (i1 PredRegs:$src1), -1, 0))>;
2821
2822 // i1 -> i64
2823 def : Pat <(i64 (sext (i1 PredRegs:$src1))),
2824       (i64 (COMBINE_rr (TFRI -1), (MUX_ii (i1 PredRegs:$src1), -1, 0)))>;
2825
2826 // Convert sign-extended load back to load and sign extend.
2827 // i8 -> i64
2828 def:  Pat <(i64 (sextloadi8 ADDRriS11_0:$src1)),
2829       (i64 (SXTW (LDrib ADDRriS11_0:$src1)))>;
2830
2831 // Convert any-extended load back to load and sign extend.
2832 // i8 -> i64
2833 def:  Pat <(i64 (extloadi8 ADDRriS11_0:$src1)),
2834       (i64 (SXTW (LDrib ADDRriS11_0:$src1)))>;
2835
2836 // Convert sign-extended load back to load and sign extend.
2837 // i16 -> i64
2838 def:  Pat <(i64 (sextloadi16 ADDRriS11_1:$src1)),
2839       (i64 (SXTW (LDrih ADDRriS11_1:$src1)))>;
2840
2841 // Convert sign-extended load back to load and sign extend.
2842 // i32 -> i64
2843 def:  Pat <(i64 (sextloadi32 ADDRriS11_2:$src1)),
2844       (i64 (SXTW (LDriw ADDRriS11_2:$src1)))>;
2845
2846
2847 // Zero extends.
2848 // i1 -> i32
2849 def : Pat <(i32 (zext (i1 PredRegs:$src1))),
2850       (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))>;
2851
2852 // i1 -> i64
2853 def : Pat <(i64 (zext (i1 PredRegs:$src1))),
2854       (i64 (COMBINE_rr (TFRI 0), (MUX_ii (i1 PredRegs:$src1), 1, 0)))>,
2855       Requires<[NoV4T]>;
2856
2857 // i32 -> i64
2858 def : Pat <(i64 (zext (i32 IntRegs:$src1))),
2859       (i64 (COMBINE_rr (TFRI 0), (i32 IntRegs:$src1)))>,
2860       Requires<[NoV4T]>;
2861
2862 // i8 -> i64
2863 def:  Pat <(i64 (zextloadi8 ADDRriS11_0:$src1)),
2864       (i64 (COMBINE_rr (TFRI 0), (LDriub ADDRriS11_0:$src1)))>,
2865       Requires<[NoV4T]>;
2866
2867 let AddedComplexity = 20 in
2868 def:  Pat <(i64 (zextloadi8 (add (i32 IntRegs:$src1),
2869                                 s11_0ExtPred:$offset))),
2870       (i64 (COMBINE_rr (TFRI 0), (LDriub_indexed IntRegs:$src1,
2871                                   s11_0ExtPred:$offset)))>,
2872       Requires<[NoV4T]>;
2873
2874 // i16 -> i64
2875 def:  Pat <(i64 (zextloadi16 ADDRriS11_1:$src1)),
2876       (i64 (COMBINE_rr (TFRI 0), (LDriuh ADDRriS11_1:$src1)))>,
2877       Requires<[NoV4T]>;
2878
2879 let AddedComplexity = 20 in
2880 def:  Pat <(i64 (zextloadi16 (add (i32 IntRegs:$src1),
2881                                   s11_1ExtPred:$offset))),
2882       (i64 (COMBINE_rr (TFRI 0), (LDriuh_indexed IntRegs:$src1,
2883                                   s11_1ExtPred:$offset)))>,
2884       Requires<[NoV4T]>;
2885
2886 // i32 -> i64
2887 def:  Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)),
2888       (i64 (COMBINE_rr (TFRI 0), (LDriw ADDRriS11_2:$src1)))>,
2889       Requires<[NoV4T]>;
2890
2891 def:  Pat <(i32 (zextloadi1 ADDRriS11_0:$src1)),
2892       (i32 (LDriw ADDRriS11_0:$src1))>;
2893
2894 // Map from Rs = Pd to Pd = mux(Pd, #1, #0)
2895 def : Pat <(i32 (zext (i1 PredRegs:$src1))),
2896       (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))>;
2897
2898 // Map from Rs = Pd to Pd = mux(Pd, #1, #0)
2899 def : Pat <(i32 (anyext (i1 PredRegs:$src1))),
2900       (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))>;
2901
2902 // Map from Rss = Pd to Rdd = sxtw (mux(Pd, #1, #0))
2903 def : Pat <(i64 (anyext (i1 PredRegs:$src1))),
2904       (i64 (SXTW (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))))>;
2905
2906
2907 // Any extended 64-bit load.
2908 // anyext i32 -> i64
2909 def:  Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
2910       (i64 (COMBINE_rr (TFRI 0), (LDriw ADDRriS11_2:$src1)))>,
2911       Requires<[NoV4T]>;
2912
2913 // When there is an offset we should prefer the pattern below over the pattern above.
2914 // The complexity of the above is 13 (gleaned from HexagonGenDAGIsel.inc)
2915 // So this complexity below is comfortably higher to allow for choosing the below.
2916 // If this is not done then we generate addresses such as
2917 // ********************************************
2918 //        r1 = add (r0, #4)
2919 //        r1 = memw(r1 + #0)
2920 //  instead of
2921 //        r1 = memw(r0 + #4)
2922 // ********************************************
2923 let AddedComplexity = 100 in
2924 def:  Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
2925       (i64 (COMBINE_rr (TFRI 0), (LDriw_indexed IntRegs:$src1,
2926                                   s11_2ExtPred:$offset)))>,
2927       Requires<[NoV4T]>;
2928
2929 // anyext i16 -> i64.
2930 def:  Pat <(i64 (extloadi16 ADDRriS11_2:$src1)),
2931       (i64 (COMBINE_rr (TFRI 0), (LDrih ADDRriS11_2:$src1)))>,
2932       Requires<[NoV4T]>;
2933
2934 let AddedComplexity = 20 in
2935 def:  Pat <(i64 (extloadi16 (add (i32 IntRegs:$src1),
2936                                   s11_1ExtPred:$offset))),
2937       (i64 (COMBINE_rr (TFRI 0), (LDrih_indexed IntRegs:$src1,
2938                                   s11_1ExtPred:$offset)))>,
2939       Requires<[NoV4T]>;
2940
2941 // Map from Rdd = zxtw(Rs) -> Rdd = combine(0, Rs).
2942 def : Pat<(i64 (zext (i32 IntRegs:$src1))),
2943       (i64 (COMBINE_rr (TFRI 0), (i32 IntRegs:$src1)))>,
2944       Requires<[NoV4T]>;
2945
2946 // Multiply 64-bit unsigned and use upper result.
2947 def : Pat <(mulhu (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
2948       (i64
2949        (MPYU64_acc
2950         (i64
2951          (COMBINE_rr
2952           (TFRI 0),
2953            (i32
2954             (EXTRACT_SUBREG
2955              (i64
2956               (LSRd_ri
2957                (i64
2958                 (MPYU64_acc
2959                  (i64
2960                   (MPYU64_acc
2961                    (i64
2962                     (COMBINE_rr (TFRI 0),
2963                      (i32
2964                       (EXTRACT_SUBREG
2965                        (i64
2966                         (LSRd_ri
2967                          (i64
2968                           (MPYU64 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
2969                                                        subreg_loreg)),
2970                                   (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2),
2971                                                        subreg_loreg)))), 32)),
2972                        subreg_loreg)))),
2973                   (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_hireg)),
2974                   (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_loreg)))),
2975                  (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_loreg)),
2976                  (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg)))),
2977                32)), subreg_loreg)))),
2978         (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_hireg)),
2979         (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg))))>;
2980
2981 // Multiply 64-bit signed and use upper result.
2982 def : Pat <(mulhs (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
2983       (i64
2984        (MPY64_acc
2985         (i64
2986          (COMBINE_rr (TFRI 0),
2987           (i32
2988            (EXTRACT_SUBREG
2989             (i64
2990              (LSRd_ri
2991               (i64
2992                (MPY64_acc
2993                 (i64
2994                  (MPY64_acc
2995                   (i64
2996                    (COMBINE_rr (TFRI 0),
2997                     (i32
2998                      (EXTRACT_SUBREG
2999                       (i64
3000                        (LSRd_ri
3001                         (i64
3002                          (MPYU64 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
3003                                                       subreg_loreg)),
3004                                  (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2),
3005                                                       subreg_loreg)))), 32)),
3006                       subreg_loreg)))),
3007                   (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_hireg)),
3008                   (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_loreg)))),
3009                 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_loreg)),
3010                 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg)))),
3011               32)), subreg_loreg)))),
3012         (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_hireg)),
3013         (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg))))>;
3014
3015 // Hexagon specific ISD nodes.
3016 //def SDTHexagonADJDYNALLOC : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>]>;
3017 def SDTHexagonADJDYNALLOC : SDTypeProfile<1, 2,
3018                                   [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
3019 def Hexagon_ADJDYNALLOC : SDNode<"HexagonISD::ADJDYNALLOC",
3020                                   SDTHexagonADJDYNALLOC>;
3021 // Needed to tag these instructions for stack layout.
3022 let usesCustomInserter = 1 in
3023 def ADJDYNALLOC : ALU32_ri<(outs IntRegs:$dst), (ins IntRegs:$src1,
3024                                                      s16Imm:$src2),
3025                   "$dst = add($src1, #$src2)",
3026                   [(set (i32 IntRegs:$dst),
3027                         (Hexagon_ADJDYNALLOC (i32 IntRegs:$src1),
3028                                              s16ImmPred:$src2))]>;
3029
3030 def SDTHexagonARGEXTEND : SDTypeProfile<1, 1, [SDTCisVT<0, i32>]>;
3031 def Hexagon_ARGEXTEND : SDNode<"HexagonISD::ARGEXTEND", SDTHexagonARGEXTEND>;
3032 def ARGEXTEND : ALU32_rr <(outs IntRegs:$dst), (ins IntRegs:$src1),
3033                 "$dst = $src1",
3034                 [(set (i32 IntRegs:$dst),
3035                       (Hexagon_ARGEXTEND (i32 IntRegs:$src1)))]>;
3036
3037 let AddedComplexity = 100 in
3038 def : Pat<(i32 (sext_inreg (Hexagon_ARGEXTEND (i32 IntRegs:$src1)), i16)),
3039       (COPY (i32 IntRegs:$src1))>;
3040
3041 def SDHexagonBR_JT: SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
3042 def HexagonBR_JT: SDNode<"HexagonISD::BR_JT", SDHexagonBR_JT, [SDNPHasChain]>;
3043
3044 let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in
3045 def BR_JT : JRInst<(outs), (ins IntRegs:$src),
3046                    "jumpr $src",
3047                    [(HexagonBR_JT (i32 IntRegs:$src))]>;
3048
3049 def HexagonWrapperJT: SDNode<"HexagonISD::WrapperJT", SDTIntUnaryOp>;
3050
3051 def : Pat<(HexagonWrapperJT tjumptable:$dst),
3052           (i32 (CONST32_set_jt tjumptable:$dst))>;
3053
3054 // XTYPE/SHIFT
3055
3056 // Multi-class for logical operators :
3057 // Shift by immediate/register and accumulate/logical
3058 multiclass xtype_imm<string OpcStr, SDNode OpNode1, SDNode OpNode2> {
3059   def _ri : SInst_acc<(outs IntRegs:$dst),
3060             (ins IntRegs:$src1, IntRegs:$src2, u5Imm:$src3),
3061             !strconcat("$dst ", !strconcat(OpcStr, "($src2, #$src3)")),
3062             [(set (i32 IntRegs:$dst),
3063                   (OpNode2 (i32 IntRegs:$src1),
3064                            (OpNode1 (i32 IntRegs:$src2),
3065                                     u5ImmPred:$src3)))],
3066             "$src1 = $dst">;
3067
3068   def d_ri : SInst_acc<(outs DoubleRegs:$dst),
3069             (ins DoubleRegs:$src1, DoubleRegs:$src2, u6Imm:$src3),
3070             !strconcat("$dst ", !strconcat(OpcStr, "($src2, #$src3)")),
3071             [(set (i64 DoubleRegs:$dst), (OpNode2 (i64 DoubleRegs:$src1),
3072                           (OpNode1 (i64 DoubleRegs:$src2), u6ImmPred:$src3)))],
3073             "$src1 = $dst">;
3074 }
3075
3076 // Multi-class for logical operators :
3077 // Shift by register and accumulate/logical (32/64 bits)
3078 multiclass xtype_reg<string OpcStr, SDNode OpNode1, SDNode OpNode2> {
3079   def _rr : SInst_acc<(outs IntRegs:$dst),
3080             (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
3081             !strconcat("$dst ", !strconcat(OpcStr, "($src2, $src3)")),
3082             [(set (i32 IntRegs:$dst),
3083                   (OpNode2 (i32 IntRegs:$src1),
3084                            (OpNode1 (i32 IntRegs:$src2),
3085                                     (i32 IntRegs:$src3))))],
3086             "$src1 = $dst">;
3087
3088   def d_rr : SInst_acc<(outs DoubleRegs:$dst),
3089             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
3090             !strconcat("$dst ", !strconcat(OpcStr, "($src2, $src3)")),
3091             [(set (i64 DoubleRegs:$dst),
3092                   (OpNode2 (i64 DoubleRegs:$src1),
3093                            (OpNode1 (i64 DoubleRegs:$src2),
3094                                     (i32 IntRegs:$src3))))],
3095             "$src1 = $dst">;
3096
3097 }
3098
3099 multiclass basic_xtype_imm<string OpcStr, SDNode OpNode> {
3100 let AddedComplexity = 100 in
3101   defm _ADD : xtype_imm< !strconcat("+= ", OpcStr), OpNode, add>;
3102   defm _SUB : xtype_imm< !strconcat("-= ", OpcStr), OpNode, sub>;
3103   defm _AND : xtype_imm< !strconcat("&= ", OpcStr), OpNode, and>;
3104   defm _OR  : xtype_imm< !strconcat("|= ", OpcStr), OpNode, or>;
3105 }
3106
3107 multiclass basic_xtype_reg<string OpcStr, SDNode OpNode> {
3108 let AddedComplexity = 100 in
3109   defm _ADD : xtype_reg< !strconcat("+= ", OpcStr), OpNode, add>;
3110   defm _SUB : xtype_reg< !strconcat("-= ", OpcStr), OpNode, sub>;
3111   defm _AND : xtype_reg< !strconcat("&= ", OpcStr), OpNode, and>;
3112   defm _OR  : xtype_reg< !strconcat("|= ", OpcStr), OpNode, or>;
3113 }
3114
3115 multiclass xtype_xor_imm<string OpcStr, SDNode OpNode> {
3116 let AddedComplexity = 100 in
3117   defm _XOR : xtype_imm< !strconcat("^= ", OpcStr), OpNode, xor>;
3118 }
3119
3120 defm ASL : basic_xtype_imm<"asl", shl>, basic_xtype_reg<"asl", shl>,
3121            xtype_xor_imm<"asl", shl>;
3122
3123 defm LSR : basic_xtype_imm<"lsr", srl>, basic_xtype_reg<"lsr", srl>,
3124            xtype_xor_imm<"lsr", srl>;
3125
3126 defm ASR : basic_xtype_imm<"asr", sra>, basic_xtype_reg<"asr", sra>;
3127 defm LSL : basic_xtype_reg<"lsl", shl>;
3128
3129 // Change the sign of the immediate for Rd=-mpyi(Rs,#u8)
3130 def : Pat <(mul (i32 IntRegs:$src1), (ineg n8ImmPred:$src2)),
3131       (i32 (MPYI_rin (i32 IntRegs:$src1), u8ImmPred:$src2))>;
3132
3133 //===----------------------------------------------------------------------===//
3134 // V3 Instructions +
3135 //===----------------------------------------------------------------------===//
3136
3137 include "HexagonInstrInfoV3.td"
3138
3139 //===----------------------------------------------------------------------===//
3140 // V3 Instructions -
3141 //===----------------------------------------------------------------------===//
3142
3143 //===----------------------------------------------------------------------===//
3144 // V4 Instructions +
3145 //===----------------------------------------------------------------------===//
3146
3147 include "HexagonInstrInfoV4.td"
3148
3149 //===----------------------------------------------------------------------===//
3150 // V4 Instructions -
3151 //===----------------------------------------------------------------------===//
3152
3153 //===----------------------------------------------------------------------===//
3154 // V5 Instructions +
3155 //===----------------------------------------------------------------------===//
3156
3157 include "HexagonInstrInfoV5.td"
3158
3159 //===----------------------------------------------------------------------===//
3160 // V5 Instructions -
3161 //===----------------------------------------------------------------------===//