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