OSDN Git Service

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