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