]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/Hexagon/HexagonPatterns.td
Merge lld trunk r300422 and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / Hexagon / HexagonPatterns.td
1 // Pattern fragment that combines the value type and the register class
2 // into a single parameter.
3 // The pat frags in the definitions below need to have a named register,
4 // otherwise i32 will be assumed regardless of the register class. The
5 // name of the register does not matter.
6 def I1  : PatLeaf<(i1 PredRegs:$R)>;
7 def I32 : PatLeaf<(i32 IntRegs:$R)>;
8 def I64 : PatLeaf<(i64 DoubleRegs:$R)>;
9 def F32 : PatLeaf<(f32 IntRegs:$R)>;
10 def F64 : PatLeaf<(f64 DoubleRegs:$R)>;
11
12 // Pattern fragments to extract the low and high subregisters from a
13 // 64-bit value.
14 def LoReg: OutPatFrag<(ops node:$Rs), (EXTRACT_SUBREG (i64 $Rs), isub_lo)>;
15 def HiReg: OutPatFrag<(ops node:$Rs), (EXTRACT_SUBREG (i64 $Rs), isub_hi)>;
16
17 def IsOrAdd: PatFrag<(ops node:$Addr, node:$off),
18     (or node:$Addr, node:$off), [{ return isOrEquivalentToAdd(N); }]>;
19
20 def Iss4_6 : PatLeaf<(i32 imm), [{
21   int32_t V = N->getSExtValue();
22   return isShiftedInt<4,6>(V);
23 }]>;
24
25 def Iss4_7 : PatLeaf<(i32 imm), [{
26   int32_t V = N->getSExtValue();
27   return isShiftedInt<4,7>(V);
28 }]>;
29
30 def IsPow2_32 : PatLeaf<(i32 imm), [{
31   uint32_t V = N->getZExtValue();
32   return isPowerOf2_32(V);
33 }]>;
34
35 def IsPow2_64 : PatLeaf<(i64 imm), [{
36   uint64_t V = N->getZExtValue();
37   return isPowerOf2_64(V);
38 }]>;
39
40 def IsNPow2_32 : PatLeaf<(i32 imm), [{
41   uint32_t NV = ~N->getZExtValue();
42   return isPowerOf2_32(NV);
43 }]>;
44
45 def IsPow2_64L : PatLeaf<(i64 imm), [{
46   uint64_t V = N->getZExtValue();
47   return isPowerOf2_64(V) && Log2_64(V) < 32;
48 }]>;
49
50 def IsPow2_64H : PatLeaf<(i64 imm), [{
51   uint64_t V = N->getZExtValue();
52   return isPowerOf2_64(V) && Log2_64(V) >= 32;
53 }]>;
54
55 def IsNPow2_64L : PatLeaf<(i64 imm), [{
56   uint64_t NV = ~N->getZExtValue();
57   return isPowerOf2_64(NV) && Log2_64(NV) < 32;
58 }]>;
59
60 def IsNPow2_64H : PatLeaf<(i64 imm), [{
61   uint64_t NV = ~N->getZExtValue();
62   return isPowerOf2_64(NV) && Log2_64(NV) >= 32;
63 }]>;
64
65 def SDEC1 : SDNodeXForm<imm, [{
66   int32_t V = N->getSExtValue();
67   return CurDAG->getTargetConstant(V-1, SDLoc(N), MVT::i32);
68 }]>;
69
70 def UDEC1 : SDNodeXForm<imm, [{
71   uint32_t V = N->getZExtValue();
72   assert(V >= 1);
73   return CurDAG->getTargetConstant(V-1, SDLoc(N), MVT::i32);
74 }]>;
75
76 def UDEC32 : SDNodeXForm<imm, [{
77   uint32_t V = N->getZExtValue();
78   assert(V >= 32);
79   return CurDAG->getTargetConstant(V-32, SDLoc(N), MVT::i32);
80 }]>;
81
82 def Log2_32 : SDNodeXForm<imm, [{
83   uint32_t V = N->getZExtValue();
84   return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32);
85 }]>;
86
87 def Log2_64 : SDNodeXForm<imm, [{
88   uint64_t V = N->getZExtValue();
89   return CurDAG->getTargetConstant(Log2_64(V), SDLoc(N), MVT::i32);
90 }]>;
91
92 def LogN2_32 : SDNodeXForm<imm, [{
93   uint32_t NV = ~N->getZExtValue();
94   return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32);
95 }]>;
96
97 def LogN2_64 : SDNodeXForm<imm, [{
98   uint64_t NV = ~N->getZExtValue();
99   return CurDAG->getTargetConstant(Log2_64(NV), SDLoc(N), MVT::i32);
100 }]>;
101
102 def ToZext64: OutPatFrag<(ops node:$Rs),
103   (i64 (A4_combineir 0, (i32 $Rs)))>;
104 def ToSext64: OutPatFrag<(ops node:$Rs),
105   (i64 (A2_sxtw (i32 $Rs)))>;
106
107
108 class T_CMP_pat <InstHexagon MI, PatFrag OpNode, PatLeaf ImmPred>
109   : Pat<(i1 (OpNode I32:$src1, ImmPred:$src2)),
110         (MI IntRegs:$src1, ImmPred:$src2)>;
111
112 def : T_CMP_pat <C2_cmpeqi,  seteq,  s10_0ImmPred>;
113 def : T_CMP_pat <C2_cmpgti,  setgt,  s10_0ImmPred>;
114 def : T_CMP_pat <C2_cmpgtui, setugt, u9_0ImmPred>;
115
116 def SDTHexagonI64I32I32 : SDTypeProfile<1, 2,
117   [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
118
119 def HexagonCOMBINE : SDNode<"HexagonISD::COMBINE", SDTHexagonI64I32I32>;
120 def HexagonPACKHL  : SDNode<"HexagonISD::PACKHL",  SDTHexagonI64I32I32>;
121
122 // Pats for instruction selection.
123 class BinOp32_pat<SDNode Op, InstHexagon MI, ValueType ResT>
124   : Pat<(ResT (Op I32:$Rs, I32:$Rt)),
125         (ResT (MI IntRegs:$Rs, IntRegs:$Rt))>;
126
127 def: BinOp32_pat<add, A2_add, i32>;
128 def: BinOp32_pat<and, A2_and, i32>;
129 def: BinOp32_pat<or,  A2_or,  i32>;
130 def: BinOp32_pat<sub, A2_sub, i32>;
131 def: BinOp32_pat<xor, A2_xor, i32>;
132
133 def: BinOp32_pat<HexagonCOMBINE, A2_combinew, i64>;
134 def: BinOp32_pat<HexagonPACKHL,  S2_packhl,   i64>;
135
136 // Patfrag to convert the usual comparison patfrags (e.g. setlt) to ones
137 // that reverse the order of the operands.
138 class RevCmp<PatFrag F> : PatFrag<(ops node:$rhs, node:$lhs), F.Fragment>;
139
140 // Pats for compares. They use PatFrags as operands, not SDNodes,
141 // since seteq/setgt/etc. are defined as ParFrags.
142 class T_cmp32_rr_pat<InstHexagon MI, PatFrag Op, ValueType VT>
143   : Pat<(VT (Op I32:$Rs, I32:$Rt)),
144         (MI IntRegs:$Rs, IntRegs:$Rt)>;
145
146 def: T_cmp32_rr_pat<C2_cmpeq,  seteq,  i1>;
147 def: T_cmp32_rr_pat<C2_cmpgt,  setgt,  i1>;
148 def: T_cmp32_rr_pat<C2_cmpgtu, setugt, i1>;
149
150 def: T_cmp32_rr_pat<C2_cmpgt,  RevCmp<setlt>,  i1>;
151 def: T_cmp32_rr_pat<C2_cmpgtu, RevCmp<setult>, i1>;
152
153 def: Pat<(select I1:$Pu, I32:$Rs, I32:$Rt),
154          (C2_mux PredRegs:$Pu, IntRegs:$Rs, IntRegs:$Rt)>;
155
156 def: Pat<(add I32:$Rs, s32_0ImmPred:$s16),
157          (A2_addi I32:$Rs, imm:$s16)>;
158
159 def: Pat<(or I32:$Rs, s32_0ImmPred:$s10),
160          (A2_orir IntRegs:$Rs, imm:$s10)>;
161 def: Pat<(and I32:$Rs, s32_0ImmPred:$s10),
162          (A2_andir IntRegs:$Rs, imm:$s10)>;
163
164 def: Pat<(sub s32_0ImmPred:$s10, IntRegs:$Rs),
165          (A2_subri imm:$s10, IntRegs:$Rs)>;
166
167 // Rd = not(Rs) gets mapped to Rd=sub(#-1, Rs).
168 def: Pat<(not I32:$src1),
169          (A2_subri -1, IntRegs:$src1)>;
170
171 def TruncI64ToI32: SDNodeXForm<imm, [{
172   return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32);
173 }]>;
174
175 def: Pat<(s32_0ImmPred:$s16), (A2_tfrsi imm:$s16)>;
176 def: Pat<(s8_0Imm64Pred:$s8), (A2_tfrpi (TruncI64ToI32 $s8))>;
177
178 def : Pat<(select I1:$Pu, s32_0ImmPred:$s8, I32:$Rs),
179           (C2_muxri I1:$Pu, imm:$s8, I32:$Rs)>;
180
181 def : Pat<(select I1:$Pu, I32:$Rs, s32_0ImmPred:$s8),
182           (C2_muxir I1:$Pu, I32:$Rs, imm:$s8)>;
183
184 def : Pat<(select I1:$Pu, s32_0ImmPred:$s8, s8_0ImmPred:$S8),
185           (C2_muxii I1:$Pu, imm:$s8, imm:$S8)>;
186
187 def: Pat<(shl I32:$src1, (i32 16)),   (A2_aslh I32:$src1)>;
188 def: Pat<(sra I32:$src1, (i32 16)),   (A2_asrh I32:$src1)>;
189 def: Pat<(sext_inreg I32:$src1, i8),  (A2_sxtb I32:$src1)>;
190 def: Pat<(sext_inreg I32:$src1, i16), (A2_sxth I32:$src1)>;
191
192 class T_vcmp_pat<InstHexagon MI, PatFrag Op, ValueType T>
193   : Pat<(i1 (Op (T DoubleRegs:$Rss), (T DoubleRegs:$Rtt))),
194         (i1 (MI DoubleRegs:$Rss, DoubleRegs:$Rtt))>;
195
196 def: T_vcmp_pat<A2_vcmpbeq,  seteq,  v8i8>;
197 def: T_vcmp_pat<A2_vcmpbgtu, setugt, v8i8>;
198 def: T_vcmp_pat<A2_vcmpheq,  seteq,  v4i16>;
199 def: T_vcmp_pat<A2_vcmphgt,  setgt,  v4i16>;
200 def: T_vcmp_pat<A2_vcmphgtu, setugt, v4i16>;
201 def: T_vcmp_pat<A2_vcmpweq,  seteq,  v2i32>;
202 def: T_vcmp_pat<A2_vcmpwgt,  setgt,  v2i32>;
203 def: T_vcmp_pat<A2_vcmpwgtu, setugt, v2i32>;
204
205 // Add halfword.
206 def: Pat<(sext_inreg (add I32:$src1, I32:$src2), i16),
207          (A2_addh_l16_ll I32:$src1, I32:$src2)>;
208
209 def: Pat<(sra (add (shl I32:$src1, (i32 16)), I32:$src2), (i32 16)),
210          (A2_addh_l16_hl I32:$src1, I32:$src2)>;
211
212 def: Pat<(shl (add I32:$src1, I32:$src2), (i32 16)),
213          (A2_addh_h16_ll I32:$src1, I32:$src2)>;
214
215 // Subtract halfword.
216 def: Pat<(sext_inreg (sub I32:$src1, I32:$src2), i16),
217          (A2_subh_l16_ll I32:$src1, I32:$src2)>;
218
219 def: Pat<(shl (sub I32:$src1, I32:$src2), (i32 16)),
220          (A2_subh_h16_ll I32:$src1, I32:$src2)>;
221
222 // Here, depending on  the operand being selected, we'll either generate a
223 // min or max instruction.
224 // Ex:
225 // (a>b)?a:b --> max(a,b) => Here check performed is '>' and the value selected
226 // is the larger of two. So, the corresponding HexagonInst is passed in 'Inst'.
227 // (a>b)?b:a --> min(a,b) => Here check performed is '>' but the smaller value
228 // is selected and the corresponding HexagonInst is passed in 'SwapInst'.
229
230 multiclass T_MinMax_pats <PatFrag Op, PatLeaf Val,
231                           InstHexagon Inst, InstHexagon SwapInst> {
232   def: Pat<(select (i1 (Op Val:$src1, Val:$src2)), Val:$src1, Val:$src2),
233            (Inst Val:$src1, Val:$src2)>;
234   def: Pat<(select (i1 (Op Val:$src1, Val:$src2)), Val:$src2, Val:$src1),
235            (SwapInst Val:$src1, Val:$src2)>;
236 }
237
238 def IsPosHalf : PatLeaf<(i32 IntRegs:$a), [{
239   return isPositiveHalfWord(N);
240 }]>;
241
242 multiclass MinMax_pats <PatFrag Op, InstHexagon Inst, InstHexagon SwapInst> {
243   defm: T_MinMax_pats<Op, I32, Inst, SwapInst>;
244
245   def: Pat<(sext_inreg (select (i1 (Op IsPosHalf:$src1, IsPosHalf:$src2)),
246                                IsPosHalf:$src1, IsPosHalf:$src2),
247                        i16),
248            (Inst IntRegs:$src1, IntRegs:$src2)>;
249
250   def: Pat<(sext_inreg (select (i1 (Op IsPosHalf:$src1, IsPosHalf:$src2)),
251                                IsPosHalf:$src2, IsPosHalf:$src1),
252                        i16),
253            (SwapInst IntRegs:$src1, IntRegs:$src2)>;
254 }
255
256 let AddedComplexity = 200 in {
257   defm: MinMax_pats<setge,  A2_max,  A2_min>;
258   defm: MinMax_pats<setgt,  A2_max,  A2_min>;
259   defm: MinMax_pats<setle,  A2_min,  A2_max>;
260   defm: MinMax_pats<setlt,  A2_min,  A2_max>;
261   defm: MinMax_pats<setuge, A2_maxu, A2_minu>;
262   defm: MinMax_pats<setugt, A2_maxu, A2_minu>;
263   defm: MinMax_pats<setule, A2_minu, A2_maxu>;
264   defm: MinMax_pats<setult, A2_minu, A2_maxu>;
265 }
266
267 class T_cmp64_rr_pat<InstHexagon MI, PatFrag CmpOp>
268   : Pat<(i1 (CmpOp I64:$Rs, I64:$Rt)),
269         (i1 (MI DoubleRegs:$Rs, DoubleRegs:$Rt))>;
270
271 def: T_cmp64_rr_pat<C2_cmpeqp,  seteq>;
272 def: T_cmp64_rr_pat<C2_cmpgtp,  setgt>;
273 def: T_cmp64_rr_pat<C2_cmpgtup, setugt>;
274 def: T_cmp64_rr_pat<C2_cmpgtp,  RevCmp<setlt>>;
275 def: T_cmp64_rr_pat<C2_cmpgtup, RevCmp<setult>>;
276
277 def: Pat<(i64 (add I64:$Rs, I64:$Rt)), (A2_addp I64:$Rs, I64:$Rt)>;
278 def: Pat<(i64 (sub I64:$Rs, I64:$Rt)), (A2_subp I64:$Rs, I64:$Rt)>;
279
280 def: Pat<(i64 (and I64:$Rs, I64:$Rt)), (A2_andp I64:$Rs, I64:$Rt)>;
281 def: Pat<(i64 (or  I64:$Rs, I64:$Rt)), (A2_orp  I64:$Rs, I64:$Rt)>;
282 def: Pat<(i64 (xor I64:$Rs, I64:$Rt)), (A2_xorp I64:$Rs, I64:$Rt)>;
283
284 def: Pat<(i1 (not I1:$Ps)), (C2_not PredRegs:$Ps)>;
285
286 def: Pat<(i1 (and I1:$Ps, I1:$Pt)),       (C2_and  I1:$Ps, I1:$Pt)>;
287 def: Pat<(i1 (or  I1:$Ps, I1:$Pt)),       (C2_or   I1:$Ps, I1:$Pt)>;
288 def: Pat<(i1 (xor I1:$Ps, I1:$Pt)),       (C2_xor  I1:$Ps, I1:$Pt)>;
289 def: Pat<(i1 (and I1:$Ps, (not I1:$Pt))), (C2_andn I1:$Ps, I1:$Pt)>;
290 def: Pat<(i1 (or  I1:$Ps, (not I1:$Pt))), (C2_orn  I1:$Ps, I1:$Pt)>;
291
292 def retflag : SDNode<"HexagonISD::RET_FLAG", SDTNone,
293                      [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
294 def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone, [SDNPHasChain]>;
295
296 def: Pat<(br bb:$dst),                  (J2_jump b30_2Imm:$dst)>;
297 def: Pat<(brcond I1:$src1, bb:$block),  (J2_jumpt PredRegs:$src1, bb:$block)>;
298 def: Pat<(brind I32:$dst),              (J2_jumpr IntRegs:$dst)>;
299
300 def: Pat<(retflag),   (PS_jmpret (i32 R31))>;
301 def: Pat<(eh_return), (EH_RETURN_JMPR (i32 R31))>;
302
303 // Patterns to select load-indexed (i.e. load from base+offset).
304 multiclass Loadx_pat<PatFrag Load, ValueType VT, PatLeaf ImmPred,
305                      InstHexagon MI> {
306   def: Pat<(VT (Load AddrFI:$fi)), (VT (MI AddrFI:$fi, 0))>;
307   def: Pat<(VT (Load (add (i32 AddrFI:$fi), ImmPred:$Off))),
308            (VT (MI AddrFI:$fi, imm:$Off))>;
309   def: Pat<(VT (Load (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off))),
310            (VT (MI AddrFI:$fi, imm:$Off))>;
311   def: Pat<(VT (Load (add I32:$Rs, ImmPred:$Off))),
312            (VT (MI IntRegs:$Rs, imm:$Off))>;
313   def: Pat<(VT (Load I32:$Rs)), (VT (MI IntRegs:$Rs, 0))>;
314 }
315
316 let AddedComplexity = 20 in {
317   defm: Loadx_pat<load,           i32, s30_2ImmPred, L2_loadri_io>;
318   defm: Loadx_pat<load,           i64, s29_3ImmPred, L2_loadrd_io>;
319   defm: Loadx_pat<atomic_load_8 , i32, s32_0ImmPred, L2_loadrub_io>;
320   defm: Loadx_pat<atomic_load_16, i32, s31_1ImmPred, L2_loadruh_io>;
321   defm: Loadx_pat<atomic_load_32, i32, s30_2ImmPred, L2_loadri_io>;
322   defm: Loadx_pat<atomic_load_64, i64, s29_3ImmPred, L2_loadrd_io>;
323
324   defm: Loadx_pat<extloadi1,      i32, s32_0ImmPred, L2_loadrub_io>;
325   defm: Loadx_pat<extloadi8,      i32, s32_0ImmPred, L2_loadrub_io>;
326   defm: Loadx_pat<extloadi16,     i32, s31_1ImmPred, L2_loadruh_io>;
327   defm: Loadx_pat<sextloadi8,     i32, s32_0ImmPred, L2_loadrb_io>;
328   defm: Loadx_pat<sextloadi16,    i32, s31_1ImmPred, L2_loadrh_io>;
329   defm: Loadx_pat<zextloadi1,     i32, s32_0ImmPred, L2_loadrub_io>;
330   defm: Loadx_pat<zextloadi8,     i32, s32_0ImmPred, L2_loadrub_io>;
331   defm: Loadx_pat<zextloadi16,    i32, s31_1ImmPred, L2_loadruh_io>;
332   // No sextloadi1.
333 }
334
335 // Sign-extending loads of i1 need to replicate the lowest bit throughout
336 // the 32-bit value. Since the loaded value can only be 0 or 1, 0-v should
337 // do the trick.
338 let AddedComplexity = 20 in
339 def: Pat<(i32 (sextloadi1 I32:$Rs)),
340          (A2_subri 0, (L2_loadrub_io IntRegs:$Rs, 0))>;
341
342 def: Pat<(i32 (mul   I32:$src1, I32:$src2)), (M2_mpyi    I32:$src1, I32:$src2)>;
343 def: Pat<(i32 (mulhs I32:$src1, I32:$src2)), (M2_mpy_up  I32:$src1, I32:$src2)>;
344 def: Pat<(i32 (mulhu I32:$src1, I32:$src2)), (M2_mpyu_up I32:$src1, I32:$src2)>;
345
346 def: Pat<(mul IntRegs:$Rs, u32_0ImmPred:$u8),
347          (M2_mpysip IntRegs:$Rs, imm:$u8)>;
348 def: Pat<(ineg (mul IntRegs:$Rs, u8_0ImmPred:$u8)),
349          (M2_mpysin IntRegs:$Rs, imm:$u8)>;
350 def: Pat<(mul IntRegs:$src1, s32_0ImmPred:$src2),
351          (M2_mpysmi IntRegs:$src1, imm:$src2)>;
352 def: Pat<(add (mul IntRegs:$src2, u32_0ImmPred:$src3), IntRegs:$src1),
353          (M2_macsip IntRegs:$src1, IntRegs:$src2, imm:$src3)>;
354 def: Pat<(add (mul I32:$src2, I32:$src3), I32:$src1),
355          (M2_maci IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
356 def: Pat<(add (add IntRegs:$src2, u32_0ImmPred:$src3), IntRegs:$src1),
357          (M2_accii IntRegs:$src1, IntRegs:$src2, imm:$src3)>;
358 def: Pat<(add (add I32:$src2, I32:$src3), I32:$src1),
359          (M2_acci IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
360
361 class T_MType_acc_pat1 <InstHexagon MI, SDNode firstOp, SDNode secOp,
362                         PatLeaf ImmPred>
363   : Pat <(secOp IntRegs:$src1, (firstOp IntRegs:$src2, ImmPred:$src3)),
364          (MI IntRegs:$src1, IntRegs:$src2, ImmPred:$src3)>;
365
366 class T_MType_acc_pat2 <InstHexagon MI, SDNode firstOp, SDNode secOp>
367   : Pat <(i32 (secOp IntRegs:$src1, (firstOp IntRegs:$src2, IntRegs:$src3))),
368          (MI IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
369
370 def : T_MType_acc_pat2 <M2_xor_xacc, xor, xor>;
371 def : T_MType_acc_pat1 <M2_macsin, mul, sub, u32_0ImmPred>;
372
373 def : T_MType_acc_pat1 <M2_naccii, add, sub, s32_0ImmPred>;
374 def : T_MType_acc_pat2 <M2_nacci, add, sub>;
375
376 def: T_MType_acc_pat2 <M4_or_xor, xor, or>;
377 def: T_MType_acc_pat2 <M4_and_xor, xor, and>;
378 def: T_MType_acc_pat2 <M4_or_and, and, or>;
379 def: T_MType_acc_pat2 <M4_and_and, and, and>;
380 def: T_MType_acc_pat2 <M4_xor_and, and, xor>;
381 def: T_MType_acc_pat2 <M4_or_or, or, or>;
382 def: T_MType_acc_pat2 <M4_and_or, or, and>;
383 def: T_MType_acc_pat2 <M4_xor_or, or, xor>;
384
385 class T_MType_acc_pat3 <InstHexagon MI, SDNode firstOp, SDNode secOp>
386   : Pat <(secOp I32:$src1, (firstOp I32:$src2, (not I32:$src3))),
387          (MI IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
388
389 def: T_MType_acc_pat3 <M4_or_andn, and, or>;
390 def: T_MType_acc_pat3 <M4_and_andn, and, and>;
391 def: T_MType_acc_pat3 <M4_xor_andn, and, xor>;
392
393 def Aext64: PatFrag<(ops node:$Rs), (i64 (anyext node:$Rs))>;
394 def Sext64: PatFrag<(ops node:$Rs), (i64 (sext node:$Rs))>;
395 def Zext64: PatFrag<(ops node:$Rs), (i64 (zext node:$Rs))>;
396
397 // Return true if for a 32 to 64-bit sign-extended load.
398 def Sext64Ld : PatLeaf<(i64 DoubleRegs:$src1), [{
399   LoadSDNode *LD = dyn_cast<LoadSDNode>(N);
400   if (!LD)
401     return false;
402   return LD->getExtensionType() == ISD::SEXTLOAD &&
403          LD->getMemoryVT().getScalarType() == MVT::i32;
404 }]>;
405
406 def: Pat<(mul (Aext64 I32:$src1), (Aext64 I32:$src2)),
407          (M2_dpmpyuu_s0 IntRegs:$src1, IntRegs:$src2)>;
408
409 def: Pat<(mul (Sext64 I32:$src1), (Sext64 I32:$src2)),
410          (M2_dpmpyss_s0 IntRegs:$src1, IntRegs:$src2)>;
411
412 def: Pat<(mul Sext64Ld:$src1, Sext64Ld:$src2),
413          (M2_dpmpyss_s0 (LoReg DoubleRegs:$src1), (LoReg DoubleRegs:$src2))>;
414
415 // Multiply and accumulate, use full result.
416 // Rxx[+-]=mpy(Rs,Rt)
417
418 def: Pat<(add I64:$src1, (mul (Sext64 I32:$src2), (Sext64 I32:$src3))),
419          (M2_dpmpyss_acc_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
420
421 def: Pat<(sub I64:$src1, (mul (Sext64 I32:$src2), (Sext64 I32:$src3))),
422          (M2_dpmpyss_nac_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
423
424 def: Pat<(add I64:$src1, (mul (Aext64 I32:$src2), (Aext64 I32:$src3))),
425          (M2_dpmpyuu_acc_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
426
427 def: Pat<(add I64:$src1, (mul (Zext64 I32:$src2), (Zext64 I32:$src3))),
428          (M2_dpmpyuu_acc_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
429
430 def: Pat<(sub I64:$src1, (mul (Aext64 I32:$src2), (Aext64 I32:$src3))),
431          (M2_dpmpyuu_nac_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
432
433 def: Pat<(sub I64:$src1, (mul (Zext64 I32:$src2), (Zext64 I32:$src3))),
434          (M2_dpmpyuu_nac_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
435
436 class Storepi_pat<PatFrag Store, PatFrag Value, PatFrag Offset,
437                   InstHexagon MI>
438   : Pat<(Store Value:$src1, I32:$src2, Offset:$offset),
439         (MI I32:$src2, imm:$offset, Value:$src1)>;
440
441 def: Storepi_pat<post_truncsti8,  I32, s4_0ImmPred, S2_storerb_pi>;
442 def: Storepi_pat<post_truncsti16, I32, s4_1ImmPred, S2_storerh_pi>;
443 def: Storepi_pat<post_store,      I32, s4_2ImmPred, S2_storeri_pi>;
444 def: Storepi_pat<post_store,      I64, s4_3ImmPred, S2_storerd_pi>;
445
446 // Patterns for generating stores, where the address takes different forms:
447 // - frameindex,
448 // - frameindex + offset,
449 // - base + offset,
450 // - simple (base address without offset).
451 // These would usually be used together (via Storex_pat defined below), but
452 // in some cases one may want to apply different properties (such as
453 // AddedComplexity) to the individual patterns.
454 class Storex_fi_pat<PatFrag Store, PatFrag Value, InstHexagon MI>
455   : Pat<(Store Value:$Rs, AddrFI:$fi), (MI AddrFI:$fi, 0, Value:$Rs)>;
456 multiclass Storex_fi_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred,
457                              InstHexagon MI> {
458   def: Pat<(Store Value:$Rs, (add (i32 AddrFI:$fi), ImmPred:$Off)),
459            (MI AddrFI:$fi, imm:$Off, Value:$Rs)>;
460   def: Pat<(Store Value:$Rs, (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off)),
461            (MI AddrFI:$fi, imm:$Off, Value:$Rs)>;
462 }
463 multiclass Storex_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred,
464                           InstHexagon MI> {
465   def: Pat<(Store Value:$Rt, (add I32:$Rs, ImmPred:$Off)),
466            (MI IntRegs:$Rs, imm:$Off, Value:$Rt)>;
467   def: Pat<(Store Value:$Rt, (IsOrAdd I32:$Rs, ImmPred:$Off)),
468            (MI IntRegs:$Rs, imm:$Off, Value:$Rt)>;
469 }
470 class Storex_simple_pat<PatFrag Store, PatFrag Value, InstHexagon MI>
471   : Pat<(Store Value:$Rt, I32:$Rs),
472         (MI IntRegs:$Rs, 0, Value:$Rt)>;
473
474 // Patterns for generating stores, where the address takes different forms,
475 // and where the value being stored is transformed through the value modifier
476 // ValueMod.  The address forms are same as above.
477 class Storexm_fi_pat<PatFrag Store, PatFrag Value, PatFrag ValueMod,
478                      InstHexagon MI>
479   : Pat<(Store Value:$Rs, AddrFI:$fi),
480         (MI AddrFI:$fi, 0, (ValueMod Value:$Rs))>;
481 multiclass Storexm_fi_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred,
482                               PatFrag ValueMod, InstHexagon MI> {
483   def: Pat<(Store Value:$Rs, (add (i32 AddrFI:$fi), ImmPred:$Off)),
484            (MI AddrFI:$fi, imm:$Off, (ValueMod Value:$Rs))>;
485   def: Pat<(Store Value:$Rs, (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off)),
486            (MI AddrFI:$fi, imm:$Off, (ValueMod Value:$Rs))>;
487 }
488 multiclass Storexm_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred,
489                            PatFrag ValueMod, InstHexagon MI> {
490   def: Pat<(Store Value:$Rt, (add I32:$Rs, ImmPred:$Off)),
491            (MI IntRegs:$Rs, imm:$Off, (ValueMod Value:$Rt))>;
492   def: Pat<(Store Value:$Rt, (IsOrAdd I32:$Rs, ImmPred:$Off)),
493            (MI IntRegs:$Rs, imm:$Off, (ValueMod Value:$Rt))>;
494 }
495 class Storexm_simple_pat<PatFrag Store, PatFrag Value, PatFrag ValueMod,
496                          InstHexagon MI>
497   : Pat<(Store Value:$Rt, I32:$Rs),
498         (MI IntRegs:$Rs, 0, (ValueMod Value:$Rt))>;
499
500 multiclass Storex_pat<PatFrag Store, PatFrag Value, PatLeaf ImmPred,
501                       InstHexagon MI> {
502   def:  Storex_fi_pat     <Store, Value,          MI>;
503   defm: Storex_fi_add_pat <Store, Value, ImmPred, MI>;
504   defm: Storex_add_pat    <Store, Value, ImmPred, MI>;
505 }
506
507 multiclass Storexm_pat<PatFrag Store, PatFrag Value, PatLeaf ImmPred,
508                        PatFrag ValueMod, InstHexagon MI> {
509   def:  Storexm_fi_pat     <Store, Value,          ValueMod, MI>;
510   defm: Storexm_fi_add_pat <Store, Value, ImmPred, ValueMod, MI>;
511   defm: Storexm_add_pat    <Store, Value, ImmPred, ValueMod, MI>;
512 }
513
514 // Regular stores in the DAG have two operands: value and address.
515 // Atomic stores also have two, but they are reversed: address, value.
516 // To use atomic stores with the patterns, they need to have their operands
517 // swapped. This relies on the knowledge that the F.Fragment uses names
518 // "ptr" and "val".
519 class SwapSt<PatFrag F>
520   : PatFrag<(ops node:$val, node:$ptr), F.Fragment, F.PredicateCode,
521             F.OperandTransform>;
522
523 let AddedComplexity = 20 in {
524   defm: Storex_pat<truncstorei8,    I32, s32_0ImmPred, S2_storerb_io>;
525   defm: Storex_pat<truncstorei16,   I32, s31_1ImmPred, S2_storerh_io>;
526   defm: Storex_pat<store,           I32, s30_2ImmPred, S2_storeri_io>;
527   defm: Storex_pat<store,           I64, s29_3ImmPred, S2_storerd_io>;
528
529   defm: Storex_pat<SwapSt<atomic_store_8>,  I32, s32_0ImmPred, S2_storerb_io>;
530   defm: Storex_pat<SwapSt<atomic_store_16>, I32, s31_1ImmPred, S2_storerh_io>;
531   defm: Storex_pat<SwapSt<atomic_store_32>, I32, s30_2ImmPred, S2_storeri_io>;
532   defm: Storex_pat<SwapSt<atomic_store_64>, I64, s29_3ImmPred, S2_storerd_io>;
533 }
534
535 // Simple patterns should be tried with the least priority.
536 def: Storex_simple_pat<truncstorei8,    I32, S2_storerb_io>;
537 def: Storex_simple_pat<truncstorei16,   I32, S2_storerh_io>;
538 def: Storex_simple_pat<store,           I32, S2_storeri_io>;
539 def: Storex_simple_pat<store,           I64, S2_storerd_io>;
540
541 def: Storex_simple_pat<SwapSt<atomic_store_8>,  I32, S2_storerb_io>;
542 def: Storex_simple_pat<SwapSt<atomic_store_16>, I32, S2_storerh_io>;
543 def: Storex_simple_pat<SwapSt<atomic_store_32>, I32, S2_storeri_io>;
544 def: Storex_simple_pat<SwapSt<atomic_store_64>, I64, S2_storerd_io>;
545
546 let AddedComplexity = 20 in {
547   defm: Storexm_pat<truncstorei8,  I64, s32_0ImmPred, LoReg, S2_storerb_io>;
548   defm: Storexm_pat<truncstorei16, I64, s31_1ImmPred, LoReg, S2_storerh_io>;
549   defm: Storexm_pat<truncstorei32, I64, s30_2ImmPred, LoReg, S2_storeri_io>;
550 }
551
552 def: Storexm_simple_pat<truncstorei8,  I64, LoReg, S2_storerb_io>;
553 def: Storexm_simple_pat<truncstorei16, I64, LoReg, S2_storerh_io>;
554 def: Storexm_simple_pat<truncstorei32, I64, LoReg, S2_storeri_io>;
555
556 def: Pat <(Sext64 I32:$src), (A2_sxtw I32:$src)>;
557
558 def: Pat<(select (i1 (setlt I32:$src, 0)), (sub 0, I32:$src), I32:$src),
559          (A2_abs IntRegs:$src)>;
560
561 let AddedComplexity = 50 in
562 def: Pat<(xor (add (sra I32:$src, (i32 31)),
563                    I32:$src),
564               (sra I32:$src, (i32 31))),
565          (A2_abs IntRegs:$src)>;
566
567 def: Pat<(sra I32:$src, u5_0ImmPred:$u5),
568          (S2_asr_i_r IntRegs:$src, imm:$u5)>;
569 def: Pat<(srl I32:$src, u5_0ImmPred:$u5),
570          (S2_lsr_i_r IntRegs:$src, imm:$u5)>;
571 def: Pat<(shl I32:$src, u5_0ImmPred:$u5),
572          (S2_asl_i_r IntRegs:$src, imm:$u5)>;
573
574 def: Pat<(sra (add (sra I32:$src1, u5_0ImmPred:$src2), 1), (i32 1)),
575          (S2_asr_i_r_rnd IntRegs:$src1, u5_0ImmPred:$src2)>;
576
577 def : Pat<(not I64:$src1),
578           (A2_notp DoubleRegs:$src1)>;
579
580 // Count leading zeros.
581 def: Pat<(ctlz I32:$Rs), (S2_cl0 I32:$Rs)>;
582 def: Pat<(i32 (trunc (ctlz I64:$Rss))), (S2_cl0p I64:$Rss)>;
583
584 // Count trailing zeros: 32-bit.
585 def: Pat<(cttz I32:$Rs), (S2_ct0 I32:$Rs)>;
586
587 // Count leading ones.
588 def: Pat<(ctlz (not I32:$Rs)), (S2_cl1 I32:$Rs)>;
589 def: Pat<(i32 (trunc (ctlz (not I64:$Rss)))), (S2_cl1p I64:$Rss)>;
590
591 // Count trailing ones: 32-bit.
592 def: Pat<(cttz (not I32:$Rs)), (S2_ct1 I32:$Rs)>;
593
594 let AddedComplexity = 20 in { // Complexity greater than and/or/xor
595   def: Pat<(and I32:$Rs, IsNPow2_32:$V),
596            (S2_clrbit_i IntRegs:$Rs, (LogN2_32 $V))>;
597   def: Pat<(or I32:$Rs, IsPow2_32:$V),
598            (S2_setbit_i IntRegs:$Rs, (Log2_32 $V))>;
599   def: Pat<(xor I32:$Rs, IsPow2_32:$V),
600            (S2_togglebit_i IntRegs:$Rs, (Log2_32 $V))>;
601
602   def: Pat<(and I32:$Rs, (not (shl 1, I32:$Rt))),
603            (S2_clrbit_r IntRegs:$Rs, IntRegs:$Rt)>;
604   def: Pat<(or I32:$Rs, (shl 1, I32:$Rt)),
605            (S2_setbit_r IntRegs:$Rs, IntRegs:$Rt)>;
606   def: Pat<(xor I32:$Rs, (shl 1, I32:$Rt)),
607            (S2_togglebit_r IntRegs:$Rs, IntRegs:$Rt)>;
608 }
609
610 // Clr/set/toggle bit for 64-bit values with immediate bit index.
611 let AddedComplexity = 20 in { // Complexity greater than and/or/xor
612   def: Pat<(and I64:$Rss, IsNPow2_64L:$V),
613            (REG_SEQUENCE DoubleRegs,
614                 (i32 (HiReg $Rss)), isub_hi,
615                 (S2_clrbit_i (LoReg $Rss), (LogN2_64 $V)), isub_lo)>;
616   def: Pat<(and I64:$Rss, IsNPow2_64H:$V),
617            (REG_SEQUENCE DoubleRegs,
618                 (S2_clrbit_i (HiReg $Rss), (UDEC32 (i32 (LogN2_64 $V)))),
619                 isub_hi,
620                 (i32 (LoReg $Rss)), isub_lo)>;
621
622   def: Pat<(or I64:$Rss, IsPow2_64L:$V),
623            (REG_SEQUENCE DoubleRegs,
624                 (i32 (HiReg $Rss)), isub_hi,
625                 (S2_setbit_i (LoReg $Rss), (Log2_64 $V)), isub_lo)>;
626   def: Pat<(or I64:$Rss, IsPow2_64H:$V),
627            (REG_SEQUENCE DoubleRegs,
628                 (S2_setbit_i (HiReg $Rss), (UDEC32 (i32 (Log2_64 $V)))),
629                 isub_hi,
630                 (i32 (LoReg $Rss)), isub_lo)>;
631
632   def: Pat<(xor I64:$Rss, IsPow2_64L:$V),
633            (REG_SEQUENCE DoubleRegs,
634                 (i32 (HiReg $Rss)), isub_hi,
635                 (S2_togglebit_i (LoReg $Rss), (Log2_64 $V)), isub_lo)>;
636   def: Pat<(xor I64:$Rss, IsPow2_64H:$V),
637            (REG_SEQUENCE DoubleRegs,
638                 (S2_togglebit_i (HiReg $Rss), (UDEC32 (i32 (Log2_64 $V)))),
639                 isub_hi,
640                 (i32 (LoReg $Rss)), isub_lo)>;
641 }
642
643 let AddedComplexity = 20 in { // Complexity greater than cmp reg-imm.
644   def: Pat<(i1 (setne (and (shl 1, u5_0ImmPred:$u5), I32:$Rs), 0)),
645            (S2_tstbit_i IntRegs:$Rs, u5_0ImmPred:$u5)>;
646   def: Pat<(i1 (setne (and (shl 1, I32:$Rt), I32:$Rs), 0)),
647            (S2_tstbit_r IntRegs:$Rs, IntRegs:$Rt)>;
648   def: Pat<(i1 (trunc I32:$Rs)),
649            (S2_tstbit_i IntRegs:$Rs, 0)>;
650   def: Pat<(i1 (trunc I64:$Rs)),
651            (S2_tstbit_i (LoReg DoubleRegs:$Rs), 0)>;
652 }
653
654 let AddedComplexity = 20 in { // Complexity greater than compare reg-imm.
655   def: Pat<(i1 (seteq (and I32:$Rs, u6_0ImmPred:$u6), 0)),
656            (C2_bitsclri IntRegs:$Rs, u6_0ImmPred:$u6)>;
657   def: Pat<(i1 (seteq (and I32:$Rs, I32:$Rt), 0)),
658            (C2_bitsclr IntRegs:$Rs, IntRegs:$Rt)>;
659 }
660
661 let AddedComplexity = 10 in   // Complexity greater than compare reg-reg.
662 def: Pat<(i1 (seteq (and I32:$Rs, I32:$Rt), IntRegs:$Rt)),
663          (C2_bitsset IntRegs:$Rs, IntRegs:$Rt)>;
664
665 def: Pat<(or (or (shl (or (shl (i32 (extloadi8 (add I32:$b, 3))),
666                                (i32 8)),
667                           (i32 (zextloadi8 (add I32:$b, 2)))),
668                       (i32 16)),
669                  (shl (i32 (zextloadi8 (add I32:$b, 1))), (i32 8))),
670              (zextloadi8 I32:$b)),
671          (A2_swiz (L2_loadri_io IntRegs:$b, 0))>;
672
673 // Patterns for loads of i1:
674 def: Pat<(i1 (load AddrFI:$fi)),
675          (C2_tfrrp (L2_loadrub_io AddrFI:$fi, 0))>;
676 def: Pat<(i1 (load (add I32:$Rs, s32_0ImmPred:$Off))),
677          (C2_tfrrp (L2_loadrub_io IntRegs:$Rs, imm:$Off))>;
678 def: Pat<(i1 (load I32:$Rs)),
679          (C2_tfrrp (L2_loadrub_io IntRegs:$Rs, 0))>;
680
681 def I1toI32: OutPatFrag<(ops node:$Rs),
682                         (C2_muxii (i1 $Rs), 1, 0)>;
683
684 def I32toI1: OutPatFrag<(ops node:$Rs),
685                         (i1 (C2_tfrrp (i32 $Rs)))>;
686
687 defm: Storexm_pat<store, I1, s32_0ImmPred, I1toI32, S2_storerb_io>;
688 def: Storexm_simple_pat<store, I1, I1toI32, S2_storerb_io>;
689
690 def: Pat<(sra I64:$src, u6_0ImmPred:$u6),
691          (S2_asr_i_p DoubleRegs:$src, imm:$u6)>;
692 def: Pat<(srl I64:$src, u6_0ImmPred:$u6),
693          (S2_lsr_i_p DoubleRegs:$src, imm:$u6)>;
694 def: Pat<(shl I64:$src, u6_0ImmPred:$u6),
695          (S2_asl_i_p DoubleRegs:$src, imm:$u6)>;
696
697 let AddedComplexity = 100 in
698 def: Pat<(add I32:$Rt, (shl I32:$Rs, u3_0ImmPred:$u3)),
699          (S2_addasl_rrri IntRegs:$Rt, IntRegs:$Rs, imm:$u3)>;
700
701 def HexagonBARRIER: SDNode<"HexagonISD::BARRIER", SDTNone, [SDNPHasChain]>;
702 def: Pat<(HexagonBARRIER), (Y2_barrier)>;
703
704 def: Pat<(IsOrAdd (i32 AddrFI:$Rs), s32_0ImmPred:$off),
705          (PS_fi (i32 AddrFI:$Rs), s32_0ImmPred:$off)>;
706
707
708 // Support for generating global address.
709 // Taken from X86InstrInfo.td.
710 def SDTHexagonCONST32 : SDTypeProfile<1, 1, [SDTCisVT<0, i32>,
711                                              SDTCisVT<1, i32>,
712                                              SDTCisPtrTy<0>]>;
713 def HexagonCONST32    : SDNode<"HexagonISD::CONST32",    SDTHexagonCONST32>;
714 def HexagonCONST32_GP : SDNode<"HexagonISD::CONST32_GP", SDTHexagonCONST32>;
715
716 // Map TLS addressses to A2_tfrsi.
717 def: Pat<(HexagonCONST32 tglobaltlsaddr:$addr), (A2_tfrsi s32_0Imm:$addr)>;
718 def: Pat<(HexagonCONST32 bbl:$label),           (A2_tfrsi s32_0Imm:$label)>;
719
720 def: Pat<(i64 imm:$v), (CONST64 imm:$v)>;
721 def: Pat<(i1 0), (PS_false)>;
722 def: Pat<(i1 1), (PS_true)>;
723
724 // Pseudo instructions.
725 def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
726 def SDT_SPCallSeqEnd   : SDCallSeqEnd<[ SDTCisVT<0, i32>,
727                                         SDTCisVT<1, i32> ]>;
728
729 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart,
730                     [SDNPHasChain, SDNPOutGlue]>;
731 def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_SPCallSeqEnd,
732                     [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
733
734 def SDT_SPCall  : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
735
736 // For tailcalls a HexagonTCRet SDNode has 3 SDNode Properties - a chain,
737 // Optional Flag and Variable Arguments.
738 // Its 1 Operand has pointer type.
739 def HexagonTCRet : SDNode<"HexagonISD::TC_RETURN", SDT_SPCall,
740                           [SDNPHasChain,  SDNPOptInGlue, SDNPVariadic]>;
741
742
743 def: Pat<(callseq_start timm:$amt),
744           (ADJCALLSTACKDOWN imm:$amt)>;
745 def: Pat<(callseq_end timm:$amt1, timm:$amt2),
746          (ADJCALLSTACKUP imm:$amt1, imm:$amt2)>;
747
748 //Tail calls.
749 def: Pat<(HexagonTCRet tglobaladdr:$dst),
750          (PS_tailcall_i tglobaladdr:$dst)>;
751 def: Pat<(HexagonTCRet texternalsym:$dst),
752          (PS_tailcall_i texternalsym:$dst)>;
753 def: Pat<(HexagonTCRet I32:$dst),
754          (PS_tailcall_r I32:$dst)>;
755
756 // Map from r0 = and(r1, 65535) to r0 = zxth(r1)
757 def: Pat<(and I32:$src1, 65535),
758          (A2_zxth IntRegs:$src1)>;
759
760 // Map from r0 = and(r1, 255) to r0 = zxtb(r1).
761 def: Pat<(and I32:$src1, 255),
762          (A2_zxtb IntRegs:$src1)>;
763
764 // Map Add(p1, true) to p1 = not(p1).
765 //     Add(p1, false) should never be produced,
766 //     if it does, it got to be mapped to NOOP.
767 def: Pat<(add I1:$src1, -1),
768          (C2_not PredRegs:$src1)>;
769
770 // Map from p0 = pnot(p0); r0 = mux(p0, #i, #j) => r0 = mux(p0, #j, #i).
771 def: Pat<(select (not I1:$src1), s8_0ImmPred:$src2, s32_0ImmPred:$src3),
772          (C2_muxii PredRegs:$src1, s32_0ImmPred:$src3, s8_0ImmPred:$src2)>;
773
774 // Map from p0 = pnot(p0); r0 = select(p0, #i, r1)
775 // => r0 = C2_muxir(p0, r1, #i)
776 def: Pat<(select (not I1:$src1), s32_0ImmPred:$src2,
777                  I32:$src3),
778          (C2_muxir PredRegs:$src1, IntRegs:$src3, s32_0ImmPred:$src2)>;
779
780 // Map from p0 = pnot(p0); r0 = mux(p0, r1, #i)
781 // => r0 = C2_muxri (p0, #i, r1)
782 def: Pat<(select (not I1:$src1), IntRegs:$src2, s32_0ImmPred:$src3),
783          (C2_muxri PredRegs:$src1, s32_0ImmPred:$src3, IntRegs:$src2)>;
784
785 // Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump.
786 def: Pat<(brcond (not I1:$src1), bb:$offset),
787          (J2_jumpf PredRegs:$src1, bb:$offset)>;
788
789 // Map from Rdd = sign_extend_inreg(Rss, i32) -> Rdd = A2_sxtw(Rss.lo).
790 def: Pat<(i64 (sext_inreg I64:$src1, i32)),
791          (A2_sxtw (LoReg DoubleRegs:$src1))>;
792
793 // Map from Rdd = sign_extend_inreg(Rss, i16) -> Rdd = A2_sxtw(A2_sxth(Rss.lo)).
794 def: Pat<(i64 (sext_inreg I64:$src1, i16)),
795          (A2_sxtw (A2_sxth (LoReg DoubleRegs:$src1)))>;
796
797 // Map from Rdd = sign_extend_inreg(Rss, i8) -> Rdd = A2_sxtw(A2_sxtb(Rss.lo)).
798 def: Pat<(i64 (sext_inreg I64:$src1, i8)),
799          (A2_sxtw (A2_sxtb (LoReg DoubleRegs:$src1)))>;
800
801 // We want to prevent emitting pnot's as much as possible.
802 // Map brcond with an unsupported setcc to a J2_jumpf.
803 def : Pat <(brcond (i1 (setne I32:$src1, I32:$src2)),
804                         bb:$offset),
805       (J2_jumpf (C2_cmpeq I32:$src1, I32:$src2),
806                 bb:$offset)>;
807
808 def : Pat <(brcond (i1 (setne I32:$src1, s10_0ImmPred:$src2)),
809                         bb:$offset),
810       (J2_jumpf (C2_cmpeqi I32:$src1, s10_0ImmPred:$src2), bb:$offset)>;
811
812 def: Pat<(brcond (i1 (setne I1:$src1, (i1 -1))), bb:$offset),
813          (J2_jumpf PredRegs:$src1, bb:$offset)>;
814
815 def: Pat<(brcond (i1 (setne I1:$src1, (i1 0))), bb:$offset),
816          (J2_jumpt PredRegs:$src1, bb:$offset)>;
817
818 // cmp.lt(Rs, Imm) -> !cmp.ge(Rs, Imm) -> !cmp.gt(Rs, Imm-1)
819 def: Pat<(brcond (i1 (setlt I32:$src1, s8_0ImmPred:$src2)), bb:$offset),
820         (J2_jumpf (C2_cmpgti IntRegs:$src1, (SDEC1 s8_0ImmPred:$src2)),
821                   bb:$offset)>;
822
823 // Map from a 64-bit select to an emulated 64-bit mux.
824 // Hexagon does not support 64-bit MUXes; so emulate with combines.
825 def: Pat<(select I1:$src1, I64:$src2,
826                  I64:$src3),
827          (A2_combinew (C2_mux PredRegs:$src1, (HiReg DoubleRegs:$src2),
828                                               (HiReg DoubleRegs:$src3)),
829                       (C2_mux PredRegs:$src1, (LoReg DoubleRegs:$src2),
830                                               (LoReg DoubleRegs:$src3)))>;
831
832 // Map from a 1-bit select to logical ops.
833 // From LegalizeDAG.cpp: (B1 ? B2 : B3) <=> (B1 & B2)|(!B1&B3).
834 def: Pat<(select I1:$src1, I1:$src2, I1:$src3),
835          (C2_or (C2_and PredRegs:$src1, PredRegs:$src2),
836                 (C2_and (C2_not PredRegs:$src1), PredRegs:$src3))>;
837
838 // Map for truncating from 64 immediates to 32 bit immediates.
839 def: Pat<(i32 (trunc I64:$src)),
840          (LoReg DoubleRegs:$src)>;
841
842 // Map for truncating from i64 immediates to i1 bit immediates.
843 def: Pat<(i1 (trunc I64:$src)),
844          (C2_tfrrp (LoReg DoubleRegs:$src))>;
845
846 // rs <= rt -> !(rs > rt).
847 let AddedComplexity = 30 in
848 def: Pat<(i1 (setle I32:$src1, s32_0ImmPred:$src2)),
849          (C2_not (C2_cmpgti IntRegs:$src1, s32_0ImmPred:$src2))>;
850
851 // rs <= rt -> !(rs > rt).
852 def : Pat<(i1 (setle I32:$src1, I32:$src2)),
853       (i1 (C2_not (C2_cmpgt I32:$src1, I32:$src2)))>;
854
855 // Rss <= Rtt -> !(Rss > Rtt).
856 def: Pat<(i1 (setle I64:$src1, I64:$src2)),
857          (C2_not (C2_cmpgtp DoubleRegs:$src1, DoubleRegs:$src2))>;
858
859 // Map cmpne -> cmpeq.
860 // Hexagon_TODO: We should improve on this.
861 // rs != rt -> !(rs == rt).
862 let AddedComplexity = 30 in
863 def: Pat<(i1 (setne I32:$src1, s32_0ImmPred:$src2)),
864          (C2_not (C2_cmpeqi IntRegs:$src1, s32_0ImmPred:$src2))>;
865
866 // Convert setne back to xor for hexagon since we compute w/ pred registers.
867 def: Pat<(i1 (setne I1:$src1, I1:$src2)),
868          (C2_xor PredRegs:$src1, PredRegs:$src2)>;
869
870 // Map cmpne(Rss) -> !cmpew(Rss).
871 // rs != rt -> !(rs == rt).
872 def: Pat<(i1 (setne I64:$src1, I64:$src2)),
873          (C2_not (C2_cmpeqp DoubleRegs:$src1, DoubleRegs:$src2))>;
874
875 // Map cmpge(Rs, Rt) -> !cmpgt(Rs, Rt).
876 // rs >= rt -> !(rt > rs).
877 def : Pat <(i1 (setge I32:$src1, I32:$src2)),
878       (i1 (C2_not (i1 (C2_cmpgt I32:$src2, I32:$src1))))>;
879
880 // cmpge(Rs, Imm) -> cmpgt(Rs, Imm-1)
881 let AddedComplexity = 30 in
882 def: Pat<(i1 (setge I32:$src1, s32_0ImmPred:$src2)),
883          (C2_cmpgti IntRegs:$src1, (SDEC1 s32_0ImmPred:$src2))>;
884
885 // Map cmpge(Rss, Rtt) -> !cmpgt(Rtt, Rss).
886 // rss >= rtt -> !(rtt > rss).
887 def: Pat<(i1 (setge I64:$src1, I64:$src2)),
888          (C2_not (C2_cmpgtp DoubleRegs:$src2, DoubleRegs:$src1))>;
889
890 // Map cmplt(Rs, Imm) -> !cmpge(Rs, Imm).
891 // !cmpge(Rs, Imm) -> !cmpgt(Rs, Imm-1).
892 // rs < rt -> !(rs >= rt).
893 let AddedComplexity = 30 in
894 def: Pat<(i1 (setlt I32:$src1, s32_0ImmPred:$src2)),
895          (C2_not (C2_cmpgti IntRegs:$src1, (SDEC1 s32_0ImmPred:$src2)))>;
896
897 // Generate cmpgeu(Rs, #0) -> cmpeq(Rs, Rs)
898 def: Pat<(i1 (setuge I32:$src1, 0)),
899          (C2_cmpeq IntRegs:$src1, IntRegs:$src1)>;
900
901 // Generate cmpgeu(Rs, #u8) -> cmpgtu(Rs, #u8 -1)
902 def: Pat<(i1 (setuge I32:$src1, u32_0ImmPred:$src2)),
903          (C2_cmpgtui IntRegs:$src1, (UDEC1 u32_0ImmPred:$src2))>;
904
905 // Generate cmpgtu(Rs, #u9)
906 def: Pat<(i1 (setugt I32:$src1, u32_0ImmPred:$src2)),
907          (C2_cmpgtui IntRegs:$src1, u32_0ImmPred:$src2)>;
908
909 // Map from Rs >= Rt -> !(Rt > Rs).
910 // rs >= rt -> !(rt > rs).
911 def: Pat<(i1 (setuge I64:$src1, I64:$src2)),
912          (C2_not (C2_cmpgtup DoubleRegs:$src2, DoubleRegs:$src1))>;
913
914 // Map from cmpleu(Rss, Rtt) -> !cmpgtu(Rss, Rtt-1).
915 // Map from (Rs <= Rt) -> !(Rs > Rt).
916 def: Pat<(i1 (setule I64:$src1, I64:$src2)),
917          (C2_not (C2_cmpgtup DoubleRegs:$src1, DoubleRegs:$src2))>;
918
919 // Sign extends.
920 // sext i1->i32
921 def: Pat<(i32 (sext I1:$Pu)),
922          (C2_muxii I1:$Pu, -1, 0)>;
923
924 // sext i1->i64
925 def: Pat<(i64 (sext I1:$Pu)),
926          (A2_combinew (C2_muxii PredRegs:$Pu, -1, 0),
927                       (C2_muxii PredRegs:$Pu, -1, 0))>;
928
929 // Zero extends.
930 // zext i1->i32
931 def: Pat<(i32 (zext I1:$Pu)),
932          (C2_muxii PredRegs:$Pu, 1, 0)>;
933
934 // zext i1->i64
935 def: Pat<(i64 (zext I1:$Pu)),
936          (ToZext64 (C2_muxii PredRegs:$Pu, 1, 0))>;
937
938 // zext i32->i64
939 def: Pat<(Zext64 I32:$Rs),
940          (ToZext64 IntRegs:$Rs)>;
941
942 // Map from Rs = Pd to Pd = mux(Pd, #1, #0)
943 def: Pat<(i32 (anyext I1:$Pu)),
944          (C2_muxii PredRegs:$Pu, 1, 0)>;
945
946 // Map from Rss = Pd to Rdd = combine(#0, (mux(Pd, #1, #0)))
947 def: Pat<(i64 (anyext I1:$Pu)),
948          (ToZext64 (C2_muxii PredRegs:$Pu, 1, 0))>;
949
950 // Clear the sign bit in a 64-bit register.
951 def ClearSign : OutPatFrag<(ops node:$Rss),
952   (A2_combinew (S2_clrbit_i (HiReg $Rss), 31), (LoReg $Rss))>;
953
954 def MulHU : OutPatFrag<(ops node:$Rss, node:$Rtt),
955   (A2_addp
956     (M2_dpmpyuu_acc_s0
957       (S2_lsr_i_p
958         (A2_addp
959           (M2_dpmpyuu_acc_s0
960             (S2_lsr_i_p (M2_dpmpyuu_s0 (LoReg $Rss), (LoReg $Rtt)), 32),
961             (HiReg $Rss),
962             (LoReg $Rtt)),
963           (A2_combinew (A2_tfrsi 0),
964                        (LoReg (M2_dpmpyuu_s0 (LoReg $Rss), (HiReg $Rtt))))),
965         32),
966       (HiReg $Rss),
967       (HiReg $Rtt)),
968     (S2_lsr_i_p (M2_dpmpyuu_s0 (LoReg $Rss), (HiReg $Rtt)), 32))>;
969
970 // Multiply 64-bit unsigned and use upper result.
971 def : Pat <(mulhu I64:$Rss, I64:$Rtt), (MulHU $Rss, $Rtt)>;
972
973 // Multiply 64-bit signed and use upper result.
974 //
975 // For two signed 64-bit integers A and B, let A' and B' denote A and B
976 // with the sign bit cleared. Then A = -2^63*s(A) + A', where s(A) is the
977 // sign bit of A (and identically for B). With this notation, the signed
978 // product A*B can be written as:
979 //   AB = (-2^63 s(A) + A') * (-2^63 s(B) + B')
980 //      = 2^126 s(A)s(B) - 2^63 [s(A)B'+s(B)A'] + A'B'
981 //      = 2^126 s(A)s(B) + 2^63 [s(A)B'+s(B)A'] + A'B' - 2*2^63 [s(A)B'+s(B)A']
982 //      = (unsigned product AB) - 2^64 [s(A)B'+s(B)A']
983
984 def : Pat <(mulhs I64:$Rss, I64:$Rtt),
985   (A2_subp
986     (MulHU $Rss, $Rtt),
987     (A2_addp
988       (A2_andp (S2_asr_i_p $Rss, 63), (ClearSign $Rtt)),
989       (A2_andp (S2_asr_i_p $Rtt, 63), (ClearSign $Rss))))>;
990
991 // Hexagon specific ISD nodes.
992 def SDTHexagonALLOCA : SDTypeProfile<1, 2,
993       [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
994 def HexagonALLOCA : SDNode<"HexagonISD::ALLOCA", SDTHexagonALLOCA,
995       [SDNPHasChain]>;
996
997
998 def: Pat<(HexagonALLOCA I32:$Rs, (i32 imm:$A)),
999          (PS_alloca IntRegs:$Rs, imm:$A)>;
1000
1001 def HexagonJT:     SDNode<"HexagonISD::JT", SDTIntUnaryOp>;
1002 def HexagonCP:     SDNode<"HexagonISD::CP", SDTIntUnaryOp>;
1003
1004 def: Pat<(HexagonJT tjumptable:$dst), (A2_tfrsi imm:$dst)>;
1005 def: Pat<(HexagonCP tconstpool:$dst), (A2_tfrsi imm:$dst)>;
1006
1007 let AddedComplexity = 100 in
1008 def: Pat<(add I32:$src1, (sra I32:$Rs, u5_0ImmPred:$u5)), (S2_asr_i_r_acc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1009 def: Pat<(sub I32:$src1, (sra I32:$Rs, u5_0ImmPred:$u5)), (S2_asr_i_r_nac IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1010 def: Pat<(and I32:$src1, (sra I32:$Rs, u5_0ImmPred:$u5)), (S2_asr_i_r_and IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1011 def: Pat<(or I32:$src1, (sra I32:$Rs, u5_0ImmPred:$u5)), (S2_asr_i_r_or IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1012
1013 let AddedComplexity = 100 in
1014 def: Pat<(add I64:$src1, (sra I64:$Rs, u6_0ImmPred:$u5)), (S2_asr_i_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1015 def: Pat<(sub I64:$src1, (sra I64:$Rs, u6_0ImmPred:$u5)), (S2_asr_i_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1016 def: Pat<(and I64:$src1, (sra I64:$Rs, u6_0ImmPred:$u5)), (S2_asr_i_p_and DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1017 def: Pat<(or I64:$src1, (sra I64:$Rs, u6_0ImmPred:$u5)), (S2_asr_i_p_or DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1018
1019 let AddedComplexity = 100 in
1020 def: Pat<(add I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_acc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1021 def: Pat<(sub I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_nac IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1022 def: Pat<(and I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_and IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1023 def: Pat<(or I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_or IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1024 let AddedComplexity = 100 in
1025 def: Pat<(xor I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_xacc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1026
1027 let AddedComplexity = 100 in
1028 def: Pat<(add I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1029 def: Pat<(sub I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1030 def: Pat<(and I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_and DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1031 def: Pat<(or I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_or DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1032 let AddedComplexity = 100 in
1033 def: Pat<(xor I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_xacc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1034
1035 let AddedComplexity = 100 in
1036 def: Pat<(add I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_acc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1037 def: Pat<(sub I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_nac IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1038 def: Pat<(and I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_and IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1039 def: Pat<(or I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_or IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1040 let AddedComplexity = 100 in
1041 def: Pat<(xor I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_xacc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1042
1043 let AddedComplexity = 100 in
1044 def: Pat<(add I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1045 def: Pat<(sub I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1046 def: Pat<(and I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_and DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1047 def: Pat<(or I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_or DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1048 let AddedComplexity = 100 in
1049 def: Pat<(xor I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_xacc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1050
1051 let AddedComplexity = 100 in
1052 def: Pat<(add I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_asl_r_r_acc IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1053 def: Pat<(sub I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_asl_r_r_nac IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1054 def: Pat<(and I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_asl_r_r_and IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1055 def: Pat<(or I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_asl_r_r_or IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1056 let AddedComplexity = 100 in
1057 def: Pat<(add I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1058 def: Pat<(sub I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1059 def: Pat<(and I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_and DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1060 def: Pat<(or I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_or DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1061 def: Pat<(xor I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_xor DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1062
1063 let AddedComplexity = 100 in
1064 def: Pat<(add I32:$src1, (sra I32:$Rs, I32:$Rt)), (S2_asr_r_r_acc IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1065 def: Pat<(sub I32:$src1, (sra I32:$Rs, I32:$Rt)), (S2_asr_r_r_nac IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1066 def: Pat<(and I32:$src1, (sra I32:$Rs, I32:$Rt)), (S2_asr_r_r_and IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1067 def: Pat<(or I32:$src1, (sra I32:$Rs, I32:$Rt)), (S2_asr_r_r_or IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1068 let AddedComplexity = 100 in
1069 def: Pat<(add I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1070 def: Pat<(sub I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1071 def: Pat<(and I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_and DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1072 def: Pat<(or I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_or DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1073 def: Pat<(xor I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_xor DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1074
1075 let AddedComplexity = 100 in
1076 def: Pat<(add I32:$src1, (srl I32:$Rs, I32:$Rt)), (S2_lsr_r_r_acc IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1077 def: Pat<(sub I32:$src1, (srl I32:$Rs, I32:$Rt)), (S2_lsr_r_r_nac IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1078 def: Pat<(and I32:$src1, (srl I32:$Rs, I32:$Rt)), (S2_lsr_r_r_and IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1079 def: Pat<(or I32:$src1, (srl I32:$Rs, I32:$Rt)), (S2_lsr_r_r_or IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1080 let AddedComplexity = 100 in
1081 def: Pat<(add I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1082 def: Pat<(sub I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1083 def: Pat<(and I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_and DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1084 def: Pat<(or I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_or DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1085 def: Pat<(xor I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_xor DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1086
1087 let AddedComplexity = 100 in
1088 def: Pat<(add I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_lsl_r_r_acc IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1089 def: Pat<(sub I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_lsl_r_r_nac IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1090 def: Pat<(and I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_lsl_r_r_and IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1091 def: Pat<(or I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_lsl_r_r_or IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1092 let AddedComplexity = 100 in
1093 def: Pat<(add I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1094 def: Pat<(sub I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1095 def: Pat<(and I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_and DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1096 def: Pat<(or I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_or DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1097 def: Pat<(xor I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_xor DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1098
1099 def: Pat<(sra I64:$src1, I32:$src2), (S2_asr_r_p DoubleRegs:$src1, IntRegs:$src2)>;
1100 def: Pat<(srl I64:$src1, I32:$src2), (S2_lsr_r_p DoubleRegs:$src1, IntRegs:$src2)>;
1101 def: Pat<(shl I64:$src1, I32:$src2), (S2_asl_r_p DoubleRegs:$src1, IntRegs:$src2)>;
1102 def: Pat<(shl I64:$src1, I32:$src2), (S2_lsl_r_p DoubleRegs:$src1, IntRegs:$src2)>;
1103
1104 def: Pat<(sra I32:$src1, I32:$src2), (S2_asr_r_r IntRegs:$src1, IntRegs:$src2)>;
1105 def: Pat<(srl I32:$src1, I32:$src2), (S2_lsr_r_r IntRegs:$src1, IntRegs:$src2)>;
1106 def: Pat<(shl I32:$src1, I32:$src2), (S2_asl_r_r IntRegs:$src1, IntRegs:$src2)>;
1107 def: Pat<(shl I32:$src1, I32:$src2), (S2_lsl_r_r IntRegs:$src1, IntRegs:$src2)>;
1108
1109 def SDTHexagonINSERT:
1110   SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
1111                        SDTCisInt<0>, SDTCisVT<3, i32>, SDTCisVT<4, i32>]>;
1112 def SDTHexagonINSERTRP:
1113   SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
1114                        SDTCisInt<0>, SDTCisVT<3, i64>]>;
1115
1116 def HexagonINSERT   : SDNode<"HexagonISD::INSERT",   SDTHexagonINSERT>;
1117 def HexagonINSERTRP : SDNode<"HexagonISD::INSERTRP", SDTHexagonINSERTRP>;
1118
1119 def: Pat<(HexagonINSERT I32:$Rs, I32:$Rt, u5_0ImmPred:$u1, u5_0ImmPred:$u2),
1120          (S2_insert I32:$Rs, I32:$Rt, u5_0ImmPred:$u1, u5_0ImmPred:$u2)>;
1121 def: Pat<(HexagonINSERT I64:$Rs, I64:$Rt, u6_0ImmPred:$u1, u6_0ImmPred:$u2),
1122          (S2_insertp I64:$Rs, I64:$Rt, u6_0ImmPred:$u1, u6_0ImmPred:$u2)>;
1123 def: Pat<(HexagonINSERTRP I32:$Rs, I32:$Rt, I64:$Ru),
1124          (S2_insert_rp I32:$Rs, I32:$Rt, I64:$Ru)>;
1125 def: Pat<(HexagonINSERTRP I64:$Rs, I64:$Rt, I64:$Ru),
1126          (S2_insertp_rp I64:$Rs, I64:$Rt, I64:$Ru)>;
1127
1128 let AddedComplexity = 100 in
1129 def: Pat<(or (or (shl (HexagonINSERT (i32 (zextloadi8 (add I32:$b, 2))),
1130                                      (i32 (extloadi8  (add I32:$b, 3))),
1131                                      24, 8),
1132                       (i32 16)),
1133                  (shl (i32 (zextloadi8 (add I32:$b, 1))), (i32 8))),
1134              (zextloadi8 I32:$b)),
1135          (A2_swiz (L2_loadri_io I32:$b, 0))>;
1136
1137 def SDTHexagonEXTRACTU:
1138   SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<1>,
1139                        SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
1140 def SDTHexagonEXTRACTURP:
1141   SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<1>,
1142                        SDTCisVT<2, i64>]>;
1143
1144 def HexagonEXTRACTU   : SDNode<"HexagonISD::EXTRACTU",   SDTHexagonEXTRACTU>;
1145 def HexagonEXTRACTURP : SDNode<"HexagonISD::EXTRACTURP", SDTHexagonEXTRACTURP>;
1146
1147 def: Pat<(HexagonEXTRACTU I32:$src1, u5_0ImmPred:$src2, u5_0ImmPred:$src3),
1148          (S2_extractu I32:$src1, u5_0ImmPred:$src2, u5_0ImmPred:$src3)>;
1149 def: Pat<(HexagonEXTRACTU I64:$src1, u6_0ImmPred:$src2, u6_0ImmPred:$src3),
1150          (S2_extractup I64:$src1, u6_0ImmPred:$src2, u6_0ImmPred:$src3)>;
1151 def: Pat<(HexagonEXTRACTURP I32:$src1, I64:$src2),
1152          (S2_extractu_rp I32:$src1, I64:$src2)>;
1153 def: Pat<(HexagonEXTRACTURP I64:$src1, I64:$src2),
1154          (S2_extractup_rp I64:$src1, I64:$src2)>;
1155
1156 def n8_0ImmPred: PatLeaf<(i32 imm), [{
1157   int64_t V = N->getSExtValue();
1158   return -255 <= V && V <= 0;
1159 }]>;
1160
1161 // Change the sign of the immediate for Rd=-mpyi(Rs,#u8)
1162 def: Pat<(mul I32:$src1, (ineg n8_0ImmPred:$src2)),
1163          (M2_mpysin IntRegs:$src1, u8_0ImmPred:$src2)>;
1164
1165 multiclass MinMax_pats_p<PatFrag Op, InstHexagon Inst, InstHexagon SwapInst> {
1166   defm: T_MinMax_pats<Op, I64, Inst, SwapInst>;
1167 }
1168
1169 def: Pat<(add (Sext64 I32:$Rs), I64:$Rt),
1170          (A2_addsp IntRegs:$Rs, DoubleRegs:$Rt)>;
1171
1172 let AddedComplexity = 200 in {
1173   defm: MinMax_pats_p<setge,  A2_maxp,  A2_minp>;
1174   defm: MinMax_pats_p<setgt,  A2_maxp,  A2_minp>;
1175   defm: MinMax_pats_p<setle,  A2_minp,  A2_maxp>;
1176   defm: MinMax_pats_p<setlt,  A2_minp,  A2_maxp>;
1177   defm: MinMax_pats_p<setuge, A2_maxup, A2_minup>;
1178   defm: MinMax_pats_p<setugt, A2_maxup, A2_minup>;
1179   defm: MinMax_pats_p<setule, A2_minup, A2_maxup>;
1180   defm: MinMax_pats_p<setult, A2_minup, A2_maxup>;
1181 }
1182
1183 def callv3 : SDNode<"HexagonISD::CALL", SDT_SPCall,
1184            [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;
1185
1186 def callv3nr : SDNode<"HexagonISD::CALLnr", SDT_SPCall,
1187            [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;
1188
1189
1190 // Map call instruction
1191 def : Pat<(callv3 I32:$dst),
1192           (J2_callr I32:$dst)>;
1193 def : Pat<(callv3 tglobaladdr:$dst),
1194           (J2_call tglobaladdr:$dst)>;
1195 def : Pat<(callv3 texternalsym:$dst),
1196           (J2_call texternalsym:$dst)>;
1197 def : Pat<(callv3 tglobaltlsaddr:$dst),
1198           (J2_call tglobaltlsaddr:$dst)>;
1199
1200 def : Pat<(callv3nr I32:$dst),
1201           (PS_callr_nr I32:$dst)>;
1202 def : Pat<(callv3nr tglobaladdr:$dst),
1203           (PS_call_nr tglobaladdr:$dst)>;
1204 def : Pat<(callv3nr texternalsym:$dst),
1205           (PS_call_nr texternalsym:$dst)>;
1206
1207
1208 def addrga: PatLeaf<(i32 AddrGA:$Addr)>;
1209 def addrgp: PatLeaf<(i32 AddrGP:$Addr)>;
1210
1211
1212 // Pats for instruction selection.
1213
1214 // A class to embed the usual comparison patfrags within a zext to i32.
1215 // The seteq/setne frags use "lhs" and "rhs" as operands, so use the same
1216 // names, or else the frag's "body" won't match the operands.
1217 class CmpInReg<PatFrag Op>
1218   : PatFrag<(ops node:$lhs, node:$rhs),(i32 (zext (i1 Op.Fragment)))>;
1219
1220 def: T_cmp32_rr_pat<A4_rcmpeq,  CmpInReg<seteq>, i32>;
1221 def: T_cmp32_rr_pat<A4_rcmpneq, CmpInReg<setne>, i32>;
1222
1223 def: T_cmp32_rr_pat<C4_cmpneq,  setne,  i1>;
1224 def: T_cmp32_rr_pat<C4_cmplte,  setle,  i1>;
1225 def: T_cmp32_rr_pat<C4_cmplteu, setule, i1>;
1226
1227 def: T_cmp32_rr_pat<C4_cmplte,  RevCmp<setge>,  i1>;
1228 def: T_cmp32_rr_pat<C4_cmplteu, RevCmp<setuge>, i1>;
1229
1230 let AddedComplexity = 100 in {
1231   def: Pat<(i1 (seteq (and (xor I32:$Rs, I32:$Rt),
1232                        255), 0)),
1233            (A4_cmpbeq IntRegs:$Rs, IntRegs:$Rt)>;
1234   def: Pat<(i1 (setne (and (xor I32:$Rs, I32:$Rt),
1235                        255), 0)),
1236            (C2_not (A4_cmpbeq IntRegs:$Rs, IntRegs:$Rt))>;
1237   def: Pat<(i1 (seteq (and (xor I32:$Rs, I32:$Rt),
1238                            65535), 0)),
1239            (A4_cmpheq IntRegs:$Rs, IntRegs:$Rt)>;
1240   def: Pat<(i1 (setne (and (xor I32:$Rs, I32:$Rt),
1241                            65535), 0)),
1242            (C2_not (A4_cmpheq IntRegs:$Rs, IntRegs:$Rt))>;
1243 }
1244
1245 def: Pat<(i32 (zext (i1 (seteq I32:$Rs, s32_0ImmPred:$s8)))),
1246          (A4_rcmpeqi IntRegs:$Rs, s32_0ImmPred:$s8)>;
1247 def: Pat<(i32 (zext (i1 (setne I32:$Rs, s32_0ImmPred:$s8)))),
1248          (A4_rcmpneqi IntRegs:$Rs, s32_0ImmPred:$s8)>;
1249
1250 // Preserve the S2_tstbit_r generation
1251 def: Pat<(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, I32:$src2)),
1252                                          I32:$src1)), 0)))),
1253          (C2_muxii (S2_tstbit_r IntRegs:$src1, IntRegs:$src2), 1, 0)>;
1254
1255 // The complexity of the combines involving immediates should be greater
1256 // than the complexity of the combine with two registers.
1257 let AddedComplexity = 50 in {
1258 def: Pat<(HexagonCOMBINE IntRegs:$r, s32_0ImmPred:$i),
1259          (A4_combineri IntRegs:$r, s32_0ImmPred:$i)>;
1260
1261 def: Pat<(HexagonCOMBINE s32_0ImmPred:$i, IntRegs:$r),
1262          (A4_combineir s32_0ImmPred:$i, IntRegs:$r)>;
1263 }
1264
1265 // The complexity of the combine with two immediates should be greater than
1266 // the complexity of a combine involving a register.
1267 let AddedComplexity = 75 in {
1268 def: Pat<(HexagonCOMBINE s8_0ImmPred:$s8, u32_0ImmPred:$u6),
1269          (A4_combineii imm:$s8, imm:$u6)>;
1270 def: Pat<(HexagonCOMBINE s32_0ImmPred:$s8, s8_0ImmPred:$S8),
1271          (A2_combineii imm:$s8, imm:$S8)>;
1272 }
1273
1274
1275 // Patterns to generate indexed loads with different forms of the address:
1276 // - frameindex,
1277 // - base + offset,
1278 // - base (without offset).
1279 multiclass Loadxm_pat<PatFrag Load, ValueType VT, PatFrag ValueMod,
1280                       PatLeaf ImmPred, InstHexagon MI> {
1281   def: Pat<(VT (Load AddrFI:$fi)),
1282            (VT (ValueMod (MI AddrFI:$fi, 0)))>;
1283   def: Pat<(VT (Load (add AddrFI:$fi, ImmPred:$Off))),
1284            (VT (ValueMod (MI AddrFI:$fi, imm:$Off)))>;
1285   def: Pat<(VT (Load (add IntRegs:$Rs, ImmPred:$Off))),
1286            (VT (ValueMod (MI IntRegs:$Rs, imm:$Off)))>;
1287   def: Pat<(VT (Load I32:$Rs)),
1288            (VT (ValueMod (MI IntRegs:$Rs, 0)))>;
1289 }
1290
1291 defm: Loadxm_pat<extloadi1,   i64, ToZext64, s32_0ImmPred, L2_loadrub_io>;
1292 defm: Loadxm_pat<extloadi8,   i64, ToZext64, s32_0ImmPred, L2_loadrub_io>;
1293 defm: Loadxm_pat<extloadi16,  i64, ToZext64, s31_1ImmPred, L2_loadruh_io>;
1294 defm: Loadxm_pat<zextloadi1,  i64, ToZext64, s32_0ImmPred, L2_loadrub_io>;
1295 defm: Loadxm_pat<zextloadi8,  i64, ToZext64, s32_0ImmPred, L2_loadrub_io>;
1296 defm: Loadxm_pat<zextloadi16, i64, ToZext64, s31_1ImmPred, L2_loadruh_io>;
1297 defm: Loadxm_pat<sextloadi8,  i64, ToSext64, s32_0ImmPred, L2_loadrb_io>;
1298 defm: Loadxm_pat<sextloadi16, i64, ToSext64, s31_1ImmPred, L2_loadrh_io>;
1299
1300 // Map Rdd = anyext(Rs) -> Rdd = combine(#0, Rs).
1301 def: Pat<(Aext64 I32:$src1), (ToZext64 IntRegs:$src1)>;
1302
1303 multiclass T_LoadAbsReg_Pat <PatFrag ldOp, InstHexagon MI, ValueType VT = i32> {
1304   def  : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2_0ImmPred:$src2),
1305                              (HexagonCONST32 tglobaladdr:$src3)))),
1306               (MI IntRegs:$src1, u2_0ImmPred:$src2, tglobaladdr:$src3)>;
1307   def  : Pat <(VT (ldOp (add IntRegs:$src1,
1308                              (HexagonCONST32 tglobaladdr:$src2)))),
1309               (MI IntRegs:$src1, 0, tglobaladdr:$src2)>;
1310
1311   def  : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2_0ImmPred:$src2),
1312                              (HexagonCONST32 tconstpool:$src3)))),
1313               (MI IntRegs:$src1, u2_0ImmPred:$src2, tconstpool:$src3)>;
1314   def  : Pat <(VT (ldOp (add IntRegs:$src1,
1315                              (HexagonCONST32 tconstpool:$src2)))),
1316               (MI IntRegs:$src1, 0, tconstpool:$src2)>;
1317
1318   def  : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2_0ImmPred:$src2),
1319                              (HexagonCONST32 tjumptable:$src3)))),
1320               (MI IntRegs:$src1, u2_0ImmPred:$src2, tjumptable:$src3)>;
1321   def  : Pat <(VT (ldOp (add IntRegs:$src1,
1322                              (HexagonCONST32 tjumptable:$src2)))),
1323               (MI IntRegs:$src1, 0, tjumptable:$src2)>;
1324 }
1325
1326 let AddedComplexity  = 60 in {
1327 defm : T_LoadAbsReg_Pat <sextloadi8, L4_loadrb_ur>;
1328 defm : T_LoadAbsReg_Pat <zextloadi8, L4_loadrub_ur>;
1329 defm : T_LoadAbsReg_Pat <extloadi8,  L4_loadrub_ur>;
1330
1331 defm : T_LoadAbsReg_Pat <sextloadi16, L4_loadrh_ur>;
1332 defm : T_LoadAbsReg_Pat <zextloadi16, L4_loadruh_ur>;
1333 defm : T_LoadAbsReg_Pat <extloadi16,  L4_loadruh_ur>;
1334
1335 defm : T_LoadAbsReg_Pat <load, L4_loadri_ur>;
1336 defm : T_LoadAbsReg_Pat <load, L4_loadrd_ur, i64>;
1337 }
1338
1339 // 'def pats' for load instructions with base + register offset and non-zero
1340 // immediate value. Immediate value is used to left-shift the second
1341 // register operand.
1342 class Loadxs_pat<PatFrag Load, ValueType VT, InstHexagon MI>
1343   : Pat<(VT (Load (add I32:$Rs,
1344                        (i32 (shl I32:$Rt, u2_0ImmPred:$u2))))),
1345         (VT (MI IntRegs:$Rs, IntRegs:$Rt, imm:$u2))>;
1346
1347 let AddedComplexity = 40 in {
1348   def: Loadxs_pat<extloadi8,   i32, L4_loadrub_rr>;
1349   def: Loadxs_pat<zextloadi8,  i32, L4_loadrub_rr>;
1350   def: Loadxs_pat<sextloadi8,  i32, L4_loadrb_rr>;
1351   def: Loadxs_pat<extloadi16,  i32, L4_loadruh_rr>;
1352   def: Loadxs_pat<zextloadi16, i32, L4_loadruh_rr>;
1353   def: Loadxs_pat<sextloadi16, i32, L4_loadrh_rr>;
1354   def: Loadxs_pat<load,        i32, L4_loadri_rr>;
1355   def: Loadxs_pat<load,        i64, L4_loadrd_rr>;
1356 }
1357
1358 // 'def pats' for load instruction base + register offset and
1359 // zero immediate value.
1360 class Loadxs_simple_pat<PatFrag Load, ValueType VT, InstHexagon MI>
1361   : Pat<(VT (Load (add I32:$Rs, I32:$Rt))),
1362         (VT (MI IntRegs:$Rs, IntRegs:$Rt, 0))>;
1363
1364 let AddedComplexity = 20 in {
1365   def: Loadxs_simple_pat<extloadi8,   i32, L4_loadrub_rr>;
1366   def: Loadxs_simple_pat<zextloadi8,  i32, L4_loadrub_rr>;
1367   def: Loadxs_simple_pat<sextloadi8,  i32, L4_loadrb_rr>;
1368   def: Loadxs_simple_pat<extloadi16,  i32, L4_loadruh_rr>;
1369   def: Loadxs_simple_pat<zextloadi16, i32, L4_loadruh_rr>;
1370   def: Loadxs_simple_pat<sextloadi16, i32, L4_loadrh_rr>;
1371   def: Loadxs_simple_pat<load,        i32, L4_loadri_rr>;
1372   def: Loadxs_simple_pat<load,        i64, L4_loadrd_rr>;
1373 }
1374
1375 let AddedComplexity = 40 in
1376 multiclass T_StoreAbsReg_Pats <InstHexagon MI, RegisterClass RC, ValueType VT,
1377                            PatFrag stOp> {
1378  def : Pat<(stOp (VT RC:$src4),
1379                  (add (shl I32:$src1, u2_0ImmPred:$src2),
1380                       u32_0ImmPred:$src3)),
1381           (MI IntRegs:$src1, u2_0ImmPred:$src2, u32_0ImmPred:$src3, RC:$src4)>;
1382
1383  def : Pat<(stOp (VT RC:$src4),
1384                  (add (shl IntRegs:$src1, u2_0ImmPred:$src2),
1385                       (HexagonCONST32 tglobaladdr:$src3))),
1386            (MI IntRegs:$src1, u2_0ImmPred:$src2, tglobaladdr:$src3, RC:$src4)>;
1387
1388  def : Pat<(stOp (VT RC:$src4),
1389                  (add IntRegs:$src1, (HexagonCONST32 tglobaladdr:$src3))),
1390            (MI IntRegs:$src1, 0, tglobaladdr:$src3, RC:$src4)>;
1391 }
1392
1393 defm : T_StoreAbsReg_Pats <S4_storerd_ur, DoubleRegs, i64, store>;
1394 defm : T_StoreAbsReg_Pats <S4_storeri_ur, IntRegs, i32, store>;
1395 defm : T_StoreAbsReg_Pats <S4_storerb_ur, IntRegs, i32, truncstorei8>;
1396 defm : T_StoreAbsReg_Pats <S4_storerh_ur, IntRegs, i32, truncstorei16>;
1397
1398 class Storexs_pat<PatFrag Store, PatFrag Value, InstHexagon MI>
1399   : Pat<(Store Value:$Ru, (add I32:$Rs,
1400                                (i32 (shl I32:$Rt, u2_0ImmPred:$u2)))),
1401         (MI IntRegs:$Rs, IntRegs:$Rt, imm:$u2, Value:$Ru)>;
1402
1403 let AddedComplexity = 40 in {
1404   def: Storexs_pat<truncstorei8,  I32, S4_storerb_rr>;
1405   def: Storexs_pat<truncstorei16, I32, S4_storerh_rr>;
1406   def: Storexs_pat<store,         I32, S4_storeri_rr>;
1407   def: Storexs_pat<store,         I64, S4_storerd_rr>;
1408 }
1409
1410 def s30_2ProperPred  : PatLeaf<(i32 imm), [{
1411   int64_t v = (int64_t)N->getSExtValue();
1412   return isShiftedInt<30,2>(v) && !isShiftedInt<29,3>(v);
1413 }]>;
1414 def RoundTo8 : SDNodeXForm<imm, [{
1415   int32_t Imm = N->getSExtValue();
1416   return CurDAG->getTargetConstant(Imm & -8, SDLoc(N), MVT::i32);
1417 }]>;
1418
1419 let AddedComplexity = 40 in
1420 def: Pat<(store I64:$Ru, (add I32:$Rs, s30_2ProperPred:$Off)),
1421          (S2_storerd_io (A2_addi I32:$Rs, 4), (RoundTo8 $Off), I64:$Ru)>;
1422
1423 class Store_rr_pat<PatFrag Store, PatFrag Value, InstHexagon MI>
1424   : Pat<(Store Value:$Ru, (add I32:$Rs, I32:$Rt)),
1425         (MI IntRegs:$Rs, IntRegs:$Rt, 0, Value:$Ru)>;
1426
1427 let AddedComplexity = 20 in {
1428   def: Store_rr_pat<truncstorei8,  I32, S4_storerb_rr>;
1429   def: Store_rr_pat<truncstorei16, I32, S4_storerh_rr>;
1430   def: Store_rr_pat<store,         I32, S4_storeri_rr>;
1431   def: Store_rr_pat<store,         I64, S4_storerd_rr>;
1432 }
1433
1434
1435 def IMM_BYTE : SDNodeXForm<imm, [{
1436   // -1 etc is  represented as 255 etc
1437   // assigning to a byte restores our desired signed value.
1438   int8_t imm = N->getSExtValue();
1439   return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32);
1440 }]>;
1441
1442 def IMM_HALF : SDNodeXForm<imm, [{
1443   // -1 etc is  represented as 65535 etc
1444   // assigning to a short restores our desired signed value.
1445   int16_t imm = N->getSExtValue();
1446   return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32);
1447 }]>;
1448
1449 def IMM_WORD : SDNodeXForm<imm, [{
1450   // -1 etc can be represented as 4294967295 etc
1451   // Currently, it's not doing this. But some optimization
1452   // might convert -1 to a large +ve number.
1453   // assigning to a word restores our desired signed value.
1454   int32_t imm = N->getSExtValue();
1455   return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32);
1456 }]>;
1457
1458 def ToImmByte : OutPatFrag<(ops node:$R), (IMM_BYTE $R)>;
1459 def ToImmHalf : OutPatFrag<(ops node:$R), (IMM_HALF $R)>;
1460 def ToImmWord : OutPatFrag<(ops node:$R), (IMM_WORD $R)>;
1461
1462 // Emit store-immediate, but only when the stored value will not be constant-
1463 // extended. The reason for that is that there is no pass that can optimize
1464 // constant extenders in store-immediate instructions. In some cases we can
1465 // end up will a number of such stores, all of which store the same extended
1466 // value (e.g. after unrolling a loop that initializes floating point array).
1467
1468 // Predicates to determine if the 16-bit immediate is expressible as a sign-
1469 // extended 8-bit immediate. Store-immediate-halfword will ignore any bits
1470 // beyond 0..15, so we don't care what is in there.
1471
1472 def i16in8ImmPred: PatLeaf<(i32 imm), [{
1473   int64_t v = (int16_t)N->getSExtValue();
1474   return v == (int64_t)(int8_t)v;
1475 }]>;
1476
1477 // Predicates to determine if the 32-bit immediate is expressible as a sign-
1478 // extended 8-bit immediate.
1479 def i32in8ImmPred: PatLeaf<(i32 imm), [{
1480   int64_t v = (int32_t)N->getSExtValue();
1481   return v == (int64_t)(int8_t)v;
1482 }]>;
1483
1484
1485 let AddedComplexity = 40 in {
1486   // Even though the offset is not extendable in the store-immediate, we
1487   // can still generate the fi# in the base address. If the final offset
1488   // is not valid for the instruction, we will replace it with a scratch
1489   // register.
1490 //  def: Storexm_fi_pat <truncstorei8, s32_0ImmPred, ToImmByte, S4_storeirb_io>;
1491 //  def: Storexm_fi_pat <truncstorei16, i16in8ImmPred, ToImmHalf,
1492 //                       S4_storeirh_io>;
1493 //  def: Storexm_fi_pat <store, i32in8ImmPred, ToImmWord, S4_storeiri_io>;
1494
1495 //  defm: Storexm_fi_add_pat <truncstorei8, s32_0ImmPred, u6_0ImmPred, ToImmByte,
1496 //                            S4_storeirb_io>;
1497 //  defm: Storexm_fi_add_pat <truncstorei16, i16in8ImmPred, u6_1ImmPred,
1498 //                            ToImmHalf, S4_storeirh_io>;
1499 //  defm: Storexm_fi_add_pat <store, i32in8ImmPred, u6_2ImmPred, ToImmWord,
1500 //                            S4_storeiri_io>;
1501
1502   defm: Storexm_add_pat<truncstorei8, s32_0ImmPred, u6_0ImmPred, ToImmByte,
1503                         S4_storeirb_io>;
1504   defm: Storexm_add_pat<truncstorei16, i16in8ImmPred, u6_1ImmPred, ToImmHalf,
1505                         S4_storeirh_io>;
1506   defm: Storexm_add_pat<store, i32in8ImmPred, u6_2ImmPred, ToImmWord,
1507                         S4_storeiri_io>;
1508 }
1509
1510 def: Storexm_simple_pat<truncstorei8,  s32_0ImmPred, ToImmByte, S4_storeirb_io>;
1511 def: Storexm_simple_pat<truncstorei16, s32_0ImmPred, ToImmHalf, S4_storeirh_io>;
1512 def: Storexm_simple_pat<store,         s32_0ImmPred, ToImmWord, S4_storeiri_io>;
1513
1514 // op(Ps, op(Pt, Pu))
1515 class LogLog_pat<SDNode Op1, SDNode Op2, InstHexagon MI>
1516   : Pat<(i1 (Op1 I1:$Ps, (Op2 I1:$Pt, I1:$Pu))),
1517         (MI I1:$Ps, I1:$Pt, I1:$Pu)>;
1518
1519 // op(Ps, op(Pt, ~Pu))
1520 class LogLogNot_pat<SDNode Op1, SDNode Op2, InstHexagon MI>
1521   : Pat<(i1 (Op1 I1:$Ps, (Op2 I1:$Pt, (not I1:$Pu)))),
1522         (MI I1:$Ps, I1:$Pt, I1:$Pu)>;
1523
1524 def: LogLog_pat<and, and, C4_and_and>;
1525 def: LogLog_pat<and, or,  C4_and_or>;
1526 def: LogLog_pat<or,  and, C4_or_and>;
1527 def: LogLog_pat<or,  or,  C4_or_or>;
1528
1529 def: LogLogNot_pat<and, and, C4_and_andn>;
1530 def: LogLogNot_pat<and, or,  C4_and_orn>;
1531 def: LogLogNot_pat<or,  and, C4_or_andn>;
1532 def: LogLogNot_pat<or,  or,  C4_or_orn>;
1533
1534 //===----------------------------------------------------------------------===//
1535 // PIC: Support for PIC compilations. The patterns and SD nodes defined
1536 // below are needed to support code generation for PIC
1537 //===----------------------------------------------------------------------===//
1538
1539 def SDT_HexagonAtGot
1540   : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i32>]>;
1541 def SDT_HexagonAtPcrel
1542   : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
1543
1544 // AT_GOT address-of-GOT, address-of-global, offset-in-global
1545 def HexagonAtGot       : SDNode<"HexagonISD::AT_GOT", SDT_HexagonAtGot>;
1546 // AT_PCREL address-of-global
1547 def HexagonAtPcrel     : SDNode<"HexagonISD::AT_PCREL", SDT_HexagonAtPcrel>;
1548
1549 def: Pat<(HexagonAtGot I32:$got, I32:$addr, (i32 0)),
1550          (L2_loadri_io I32:$got, imm:$addr)>;
1551 def: Pat<(HexagonAtGot I32:$got, I32:$addr, s30_2ImmPred:$off),
1552          (A2_addi (L2_loadri_io I32:$got, imm:$addr), imm:$off)>;
1553 def: Pat<(HexagonAtPcrel I32:$addr),
1554          (C4_addipc imm:$addr)>;
1555
1556 def: Pat<(i64 (and I64:$Rs, (i64 (not I64:$Rt)))),
1557          (A4_andnp DoubleRegs:$Rs, DoubleRegs:$Rt)>;
1558 def: Pat<(i64 (or  I64:$Rs, (i64 (not I64:$Rt)))),
1559          (A4_ornp DoubleRegs:$Rs, DoubleRegs:$Rt)>;
1560
1561 def: Pat<(add I32:$Rs, (add I32:$Ru, s32_0ImmPred:$s6)),
1562          (S4_addaddi IntRegs:$Rs, IntRegs:$Ru, imm:$s6)>;
1563
1564 // Rd=add(Rs,sub(#s6,Ru))
1565 def: Pat<(add I32:$src1, (sub s32_0ImmPred:$src2,
1566                                         I32:$src3)),
1567          (S4_subaddi IntRegs:$src1, s32_0ImmPred:$src2, IntRegs:$src3)>;
1568
1569 // Rd=sub(add(Rs,#s6),Ru)
1570 def: Pat<(sub (add I32:$src1, s32_0ImmPred:$src2),
1571                    I32:$src3),
1572          (S4_subaddi IntRegs:$src1, s32_0ImmPred:$src2, IntRegs:$src3)>;
1573
1574 // Rd=add(sub(Rs,Ru),#s6)
1575 def: Pat<(add (sub I32:$src1, I32:$src3),
1576                    (s32_0ImmPred:$src2)),
1577          (S4_subaddi IntRegs:$src1, s32_0ImmPred:$src2, IntRegs:$src3)>;
1578
1579 def: Pat<(xor I64:$dst2,
1580               (xor I64:$Rss, I64:$Rtt)),
1581          (M4_xor_xacc DoubleRegs:$dst2, DoubleRegs:$Rss, DoubleRegs:$Rtt)>;
1582 def: Pat<(or I32:$Ru, (and (i32 IntRegs:$_src_), s32_0ImmPred:$s10)),
1583          (S4_or_andix IntRegs:$Ru, IntRegs:$_src_, imm:$s10)>;
1584
1585 def: Pat<(or I32:$src1, (and I32:$Rs, s32_0ImmPred:$s10)),
1586          (S4_or_andi IntRegs:$src1, IntRegs:$Rs, imm:$s10)>;
1587
1588 def: Pat<(or I32:$src1, (or I32:$Rs, s32_0ImmPred:$s10)),
1589          (S4_or_ori IntRegs:$src1, IntRegs:$Rs, imm:$s10)>;
1590
1591
1592
1593 // Count trailing zeros: 64-bit.
1594 def: Pat<(i32 (trunc (cttz I64:$Rss))), (S2_ct0p I64:$Rss)>;
1595
1596 // Count trailing ones: 64-bit.
1597 def: Pat<(i32 (trunc (cttz (not I64:$Rss)))), (S2_ct1p I64:$Rss)>;
1598
1599 // Define leading/trailing patterns that require zero-extensions to 64 bits.
1600 def: Pat<(i64 (ctlz I64:$Rss)), (ToZext64 (S2_cl0p I64:$Rss))>;
1601 def: Pat<(i64 (cttz I64:$Rss)), (ToZext64 (S2_ct0p I64:$Rss))>;
1602 def: Pat<(i64 (ctlz (not I64:$Rss))), (ToZext64 (S2_cl1p I64:$Rss))>;
1603 def: Pat<(i64 (cttz (not I64:$Rss))), (ToZext64 (S2_ct1p I64:$Rss))>;
1604
1605 def: Pat<(i64 (ctpop I64:$Rss)), (ToZext64 (S5_popcountp I64:$Rss))>;
1606 def: Pat<(i32 (ctpop I32:$Rs)), (S5_popcountp (A4_combineir 0, I32:$Rs))>;
1607
1608 def: Pat<(bitreverse I32:$Rs), (S2_brev I32:$Rs)>;
1609 def: Pat<(bitreverse I64:$Rss), (S2_brevp I64:$Rss)>;
1610
1611 def: Pat<(bswap I32:$Rs), (A2_swiz I32:$Rs)>;
1612 def: Pat<(bswap I64:$Rss), (A2_combinew (A2_swiz (LoReg $Rss)),
1613                                         (A2_swiz (HiReg $Rss)))>;
1614
1615 let AddedComplexity = 20 in {   // Complexity greater than cmp reg-imm.
1616   def: Pat<(i1 (seteq (and (shl 1, u5_0ImmPred:$u5), I32:$Rs), 0)),
1617            (S4_ntstbit_i I32:$Rs, u5_0ImmPred:$u5)>;
1618   def: Pat<(i1 (seteq (and (shl 1, I32:$Rt), I32:$Rs), 0)),
1619            (S4_ntstbit_r I32:$Rs, I32:$Rt)>;
1620 }
1621
1622 // Add extra complexity to prefer these instructions over bitsset/bitsclr.
1623 // The reason is that tstbit/ntstbit can be folded into a compound instruction:
1624 //   if ([!]tstbit(...)) jump ...
1625 let AddedComplexity = 100 in
1626 def: Pat<(i1 (setne (and I32:$Rs, (i32 IsPow2_32:$u5)), (i32 0))),
1627          (S2_tstbit_i I32:$Rs, (Log2_32 imm:$u5))>;
1628
1629 let AddedComplexity = 100 in
1630 def: Pat<(i1 (seteq (and I32:$Rs, (i32 IsPow2_32:$u5)), (i32 0))),
1631          (S4_ntstbit_i I32:$Rs, (Log2_32 imm:$u5))>;
1632
1633 // Do not increase complexity of these patterns. In the DAG, "cmp i8" may be
1634 // represented as a compare against "value & 0xFF", which is an exact match
1635 // for cmpb (same for cmph). The patterns below do not contain any additional
1636 // complexity that would make them preferable, and if they were actually used
1637 // instead of cmpb/cmph, they would result in a compare against register that
1638 // is loaded with the byte/half mask (i.e. 0xFF or 0xFFFF).
1639 def: Pat<(i1 (setne (and I32:$Rs, u6_0ImmPred:$u6), 0)),
1640          (C4_nbitsclri I32:$Rs, u6_0ImmPred:$u6)>;
1641 def: Pat<(i1 (setne (and I32:$Rs, I32:$Rt), 0)),
1642          (C4_nbitsclr I32:$Rs, I32:$Rt)>;
1643 def: Pat<(i1 (setne (and I32:$Rs, I32:$Rt), I32:$Rt)),
1644          (C4_nbitsset I32:$Rs, I32:$Rt)>;
1645
1646
1647 def: Pat<(add (mul I32:$Rs, u6_0ImmPred:$U6), u32_0ImmPred:$u6),
1648          (M4_mpyri_addi imm:$u6, IntRegs:$Rs, imm:$U6)>;
1649 def: Pat<(add (mul I32:$Rs, I32:$Rt), u32_0ImmPred:$u6),
1650          (M4_mpyrr_addi imm:$u6, IntRegs:$Rs, IntRegs:$Rt)>;
1651
1652 def: Pat<(add I32:$src1, (mul I32:$src3, u6_2ImmPred:$src2)),
1653          (M4_mpyri_addr_u2 IntRegs:$src1, imm:$src2, IntRegs:$src3)>;
1654 def: Pat<(add I32:$src1, (mul I32:$src3, u32_0ImmPred:$src2)),
1655          (M4_mpyri_addr IntRegs:$src1, IntRegs:$src3, imm:$src2)>;
1656
1657 def: Pat<(add I32:$Ru, (mul (i32 IntRegs:$_src_), I32:$Rs)),
1658          (M4_mpyrr_addr IntRegs:$Ru, IntRegs:$_src_, IntRegs:$Rs)>;
1659
1660 def: T_vcmp_pat<A4_vcmpbgt, setgt, v8i8>;
1661
1662 class T_Shift_CommOp_pat<InstHexagon MI, SDNode Op, SDNode ShOp>
1663   : Pat<(Op (ShOp IntRegs:$Rx, u5_0ImmPred:$U5), u32_0ImmPred:$u8),
1664         (MI u32_0ImmPred:$u8, IntRegs:$Rx, u5_0ImmPred:$U5)>;
1665
1666 let AddedComplexity = 200 in {
1667   def : T_Shift_CommOp_pat <S4_addi_asl_ri, add, shl>;
1668   def : T_Shift_CommOp_pat <S4_addi_lsr_ri, add, srl>;
1669   def : T_Shift_CommOp_pat <S4_andi_asl_ri, and, shl>;
1670   def : T_Shift_CommOp_pat <S4_andi_lsr_ri, and, srl>;
1671 }
1672
1673 let AddedComplexity = 30 in {
1674   def : T_Shift_CommOp_pat <S4_ori_asl_ri,  or,  shl>;
1675   def : T_Shift_CommOp_pat <S4_ori_lsr_ri,  or,  srl>;
1676 }
1677
1678 class T_Shift_Op_pat<InstHexagon MI, SDNode Op, SDNode ShOp>
1679   : Pat<(Op u32_0ImmPred:$u8, (ShOp IntRegs:$Rx, u5_0ImmPred:$U5)),
1680         (MI u32_0ImmPred:$u8, IntRegs:$Rx, u5_0ImmPred:$U5)>;
1681
1682 def : T_Shift_Op_pat <S4_subi_asl_ri, sub, shl>;
1683 def : T_Shift_Op_pat <S4_subi_lsr_ri, sub, srl>;
1684
1685 let AddedComplexity = 200 in {
1686   def: Pat<(add addrga:$addr, (shl I32:$src2, u5_0ImmPred:$src3)),
1687            (S4_addi_asl_ri addrga:$addr, IntRegs:$src2, u5_0ImmPred:$src3)>;
1688   def: Pat<(add addrga:$addr, (srl I32:$src2, u5_0ImmPred:$src3)),
1689            (S4_addi_lsr_ri addrga:$addr, IntRegs:$src2, u5_0ImmPred:$src3)>;
1690   def: Pat<(sub addrga:$addr, (shl I32:$src2, u5_0ImmPred:$src3)),
1691            (S4_subi_asl_ri addrga:$addr, IntRegs:$src2, u5_0ImmPred:$src3)>;
1692   def: Pat<(sub addrga:$addr, (srl I32:$src2, u5_0ImmPred:$src3)),
1693            (S4_subi_lsr_ri addrga:$addr, IntRegs:$src2, u5_0ImmPred:$src3)>;
1694 }
1695
1696 def: Pat<(shl s6_0ImmPred:$s6, I32:$Rt),
1697          (S4_lsli imm:$s6, IntRegs:$Rt)>;
1698
1699
1700 //===----------------------------------------------------------------------===//
1701 // MEMOP
1702 //===----------------------------------------------------------------------===//
1703
1704 def m5_0Imm8Pred : PatLeaf<(i32 imm), [{
1705   int8_t V = N->getSExtValue();
1706   return -32 < V && V <= -1;
1707 }]>;
1708
1709 def m5_0Imm16Pred : PatLeaf<(i32 imm), [{
1710   int16_t V = N->getSExtValue();
1711   return -32 < V && V <= -1;
1712 }]>;
1713
1714 def m5_0ImmPred  : PatLeaf<(i32 imm), [{
1715   int64_t V = N->getSExtValue();
1716   return -31 <= V && V <= -1;
1717 }]>;
1718
1719 def IsNPow2_8 : PatLeaf<(i32 imm), [{
1720   uint8_t NV = ~N->getZExtValue();
1721   return isPowerOf2_32(NV);
1722 }]>;
1723
1724 def IsNPow2_16 : PatLeaf<(i32 imm), [{
1725   uint16_t NV = ~N->getZExtValue();
1726   return isPowerOf2_32(NV);
1727 }]>;
1728
1729 def Log2_8 : SDNodeXForm<imm, [{
1730   uint8_t V = N->getZExtValue();
1731   return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32);
1732 }]>;
1733
1734 def Log2_16 : SDNodeXForm<imm, [{
1735   uint16_t V = N->getZExtValue();
1736   return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32);
1737 }]>;
1738
1739 def LogN2_8 : SDNodeXForm<imm, [{
1740   uint8_t NV = ~N->getZExtValue();
1741   return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32);
1742 }]>;
1743
1744 def LogN2_16 : SDNodeXForm<imm, [{
1745   uint16_t NV = ~N->getZExtValue();
1746   return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32);
1747 }]>;
1748
1749 def NegImm8 : SDNodeXForm<imm, [{
1750   int8_t NV = -N->getSExtValue();
1751   return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32);
1752 }]>;
1753
1754 def NegImm16 : SDNodeXForm<imm, [{
1755   int16_t NV = -N->getSExtValue();
1756   return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32);
1757 }]>;
1758
1759 def NegImm32 : SDNodeXForm<imm, [{
1760   int32_t NV = -N->getSExtValue();
1761   return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32);
1762 }]>;
1763
1764 def IdImm : SDNodeXForm<imm, [{ return SDValue(N, 0); }]>;
1765
1766 multiclass Memopxr_simple_pat<PatFrag Load, PatFrag Store, SDNode Oper,
1767                               InstHexagon MI> {
1768   // Addr: i32
1769   def: Pat<(Store (Oper (Load I32:$Rs), I32:$A), I32:$Rs),
1770            (MI I32:$Rs, 0, I32:$A)>;
1771   // Addr: fi
1772   def: Pat<(Store (Oper (Load AddrFI:$Rs), I32:$A), AddrFI:$Rs),
1773            (MI AddrFI:$Rs, 0, I32:$A)>;
1774 }
1775
1776 multiclass Memopxr_add_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred,
1777                            SDNode Oper, InstHexagon MI> {
1778   // Addr: i32
1779   def: Pat<(Store (Oper (Load (add I32:$Rs, ImmPred:$Off)), I32:$A),
1780                   (add I32:$Rs, ImmPred:$Off)),
1781            (MI I32:$Rs, imm:$Off, I32:$A)>;
1782   def: Pat<(Store (Oper (Load (IsOrAdd I32:$Rs, ImmPred:$Off)), I32:$A),
1783                   (IsOrAdd I32:$Rs, ImmPred:$Off)),
1784            (MI I32:$Rs, imm:$Off, I32:$A)>;
1785   // Addr: fi
1786   def: Pat<(Store (Oper (Load (add AddrFI:$Rs, ImmPred:$Off)), I32:$A),
1787                   (add AddrFI:$Rs, ImmPred:$Off)),
1788            (MI AddrFI:$Rs, imm:$Off, I32:$A)>;
1789   def: Pat<(Store (Oper (Load (IsOrAdd AddrFI:$Rs, ImmPred:$Off)), I32:$A),
1790                   (IsOrAdd AddrFI:$Rs, ImmPred:$Off)),
1791            (MI AddrFI:$Rs, imm:$Off, I32:$A)>;
1792 }
1793
1794 multiclass Memopxr_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred,
1795                        SDNode Oper, InstHexagon MI> {
1796   defm: Memopxr_simple_pat <Load, Store,          Oper, MI>;
1797   defm: Memopxr_add_pat    <Load, Store, ImmPred, Oper, MI>;
1798 }
1799
1800 let AddedComplexity = 180 in {
1801   // add reg
1802   defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, add,
1803         /*anyext*/  L4_add_memopb_io>;
1804   defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, add,
1805         /*sext*/    L4_add_memopb_io>;
1806   defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, add,
1807         /*zext*/    L4_add_memopb_io>;
1808   defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, add,
1809         /*anyext*/  L4_add_memoph_io>;
1810   defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, add,
1811         /*sext*/    L4_add_memoph_io>;
1812   defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, add,
1813         /*zext*/    L4_add_memoph_io>;
1814   defm: Memopxr_pat<load, store, u6_2ImmPred, add, L4_add_memopw_io>;
1815
1816   // sub reg
1817   defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, sub,
1818         /*anyext*/  L4_sub_memopb_io>;
1819   defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub,
1820         /*sext*/    L4_sub_memopb_io>;
1821   defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub,
1822         /*zext*/    L4_sub_memopb_io>;
1823   defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, sub,
1824         /*anyext*/  L4_sub_memoph_io>;
1825   defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub,
1826         /*sext*/    L4_sub_memoph_io>;
1827   defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub,
1828         /*zext*/    L4_sub_memoph_io>;
1829   defm: Memopxr_pat<load, store, u6_2ImmPred, sub, L4_sub_memopw_io>;
1830
1831   // and reg
1832   defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, and,
1833         /*anyext*/  L4_and_memopb_io>;
1834   defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, and,
1835         /*sext*/    L4_and_memopb_io>;
1836   defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, and,
1837         /*zext*/    L4_and_memopb_io>;
1838   defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, and,
1839         /*anyext*/  L4_and_memoph_io>;
1840   defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, and,
1841         /*sext*/    L4_and_memoph_io>;
1842   defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, and,
1843         /*zext*/    L4_and_memoph_io>;
1844   defm: Memopxr_pat<load, store, u6_2ImmPred, and, L4_and_memopw_io>;
1845
1846   // or reg
1847   defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, or,
1848         /*anyext*/  L4_or_memopb_io>;
1849   defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, or,
1850         /*sext*/    L4_or_memopb_io>;
1851   defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, or,
1852         /*zext*/    L4_or_memopb_io>;
1853   defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, or,
1854         /*anyext*/  L4_or_memoph_io>;
1855   defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, or,
1856         /*sext*/    L4_or_memoph_io>;
1857   defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, or,
1858         /*zext*/    L4_or_memoph_io>;
1859   defm: Memopxr_pat<load, store, u6_2ImmPred, or, L4_or_memopw_io>;
1860 }
1861
1862
1863 multiclass Memopxi_simple_pat<PatFrag Load, PatFrag Store, SDNode Oper,
1864                               PatFrag Arg, SDNodeXForm ArgMod,
1865                               InstHexagon MI> {
1866   // Addr: i32
1867   def: Pat<(Store (Oper (Load I32:$Rs), Arg:$A), I32:$Rs),
1868            (MI I32:$Rs, 0, (ArgMod Arg:$A))>;
1869   // Addr: fi
1870   def: Pat<(Store (Oper (Load AddrFI:$Rs), Arg:$A), AddrFI:$Rs),
1871            (MI AddrFI:$Rs, 0, (ArgMod Arg:$A))>;
1872 }
1873
1874 multiclass Memopxi_add_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred,
1875                            SDNode Oper, PatFrag Arg, SDNodeXForm ArgMod,
1876                            InstHexagon MI> {
1877   // Addr: i32
1878   def: Pat<(Store (Oper (Load (add I32:$Rs, ImmPred:$Off)), Arg:$A),
1879                   (add I32:$Rs, ImmPred:$Off)),
1880            (MI I32:$Rs, imm:$Off, (ArgMod Arg:$A))>;
1881   def: Pat<(Store (Oper (Load (IsOrAdd I32:$Rs, ImmPred:$Off)), Arg:$A),
1882                   (IsOrAdd I32:$Rs, ImmPred:$Off)),
1883            (MI I32:$Rs, imm:$Off, (ArgMod Arg:$A))>;
1884   // Addr: fi
1885   def: Pat<(Store (Oper (Load (add AddrFI:$Rs, ImmPred:$Off)), Arg:$A),
1886                   (add AddrFI:$Rs, ImmPred:$Off)),
1887            (MI AddrFI:$Rs, imm:$Off, (ArgMod Arg:$A))>;
1888   def: Pat<(Store (Oper (Load (IsOrAdd AddrFI:$Rs, ImmPred:$Off)), Arg:$A),
1889                   (IsOrAdd AddrFI:$Rs, ImmPred:$Off)),
1890            (MI AddrFI:$Rs, imm:$Off, (ArgMod Arg:$A))>;
1891 }
1892
1893 multiclass Memopxi_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred,
1894                        SDNode Oper, PatFrag Arg, SDNodeXForm ArgMod,
1895                        InstHexagon MI> {
1896   defm: Memopxi_simple_pat <Load, Store,          Oper, Arg, ArgMod, MI>;
1897   defm: Memopxi_add_pat    <Load, Store, ImmPred, Oper, Arg, ArgMod, MI>;
1898 }
1899
1900
1901 let AddedComplexity = 200 in {
1902   // add imm
1903   defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, add, u5_0ImmPred,
1904         /*anyext*/  IdImm, L4_iadd_memopb_io>;
1905   defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, add, u5_0ImmPred,
1906         /*sext*/    IdImm, L4_iadd_memopb_io>;
1907   defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, add, u5_0ImmPred,
1908         /*zext*/    IdImm, L4_iadd_memopb_io>;
1909   defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5_0ImmPred,
1910         /*anyext*/  IdImm, L4_iadd_memoph_io>;
1911   defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5_0ImmPred,
1912         /*sext*/    IdImm, L4_iadd_memoph_io>;
1913   defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5_0ImmPred,
1914         /*zext*/    IdImm, L4_iadd_memoph_io>;
1915   defm: Memopxi_pat<load, store, u6_2ImmPred, add, u5_0ImmPred, IdImm,
1916                     L4_iadd_memopw_io>;
1917   defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, sub, m5_0Imm8Pred,
1918         /*anyext*/  NegImm8, L4_iadd_memopb_io>;
1919   defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub, m5_0Imm8Pred,
1920         /*sext*/    NegImm8, L4_iadd_memopb_io>;
1921   defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub, m5_0Imm8Pred,
1922         /*zext*/    NegImm8, L4_iadd_memopb_io>;
1923   defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, sub, m5_0Imm16Pred,
1924         /*anyext*/  NegImm16, L4_iadd_memoph_io>;
1925   defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub, m5_0Imm16Pred,
1926         /*sext*/    NegImm16, L4_iadd_memoph_io>;
1927   defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub, m5_0Imm16Pred,
1928         /*zext*/    NegImm16, L4_iadd_memoph_io>;
1929   defm: Memopxi_pat<load, store, u6_2ImmPred, sub, m5_0ImmPred, NegImm32,
1930                     L4_iadd_memopw_io>;
1931
1932   // sub imm
1933   defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, sub, u5_0ImmPred,
1934         /*anyext*/  IdImm, L4_isub_memopb_io>;
1935   defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub, u5_0ImmPred,
1936         /*sext*/    IdImm, L4_isub_memopb_io>;
1937   defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub, u5_0ImmPred,
1938         /*zext*/    IdImm, L4_isub_memopb_io>;
1939   defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, sub, u5_0ImmPred,
1940         /*anyext*/  IdImm, L4_isub_memoph_io>;
1941   defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub, u5_0ImmPred,
1942         /*sext*/    IdImm, L4_isub_memoph_io>;
1943   defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub, u5_0ImmPred,
1944         /*zext*/    IdImm, L4_isub_memoph_io>;
1945   defm: Memopxi_pat<load, store, u6_2ImmPred, sub, u5_0ImmPred, IdImm,
1946                     L4_isub_memopw_io>;
1947   defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, add, m5_0Imm8Pred,
1948         /*anyext*/  NegImm8, L4_isub_memopb_io>;
1949   defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, add, m5_0Imm8Pred,
1950         /*sext*/    NegImm8, L4_isub_memopb_io>;
1951   defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, add, m5_0Imm8Pred,
1952         /*zext*/    NegImm8, L4_isub_memopb_io>;
1953   defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, m5_0Imm16Pred,
1954         /*anyext*/  NegImm16, L4_isub_memoph_io>;
1955   defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, add, m5_0Imm16Pred,
1956         /*sext*/    NegImm16, L4_isub_memoph_io>;
1957   defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, add, m5_0Imm16Pred,
1958         /*zext*/    NegImm16, L4_isub_memoph_io>;
1959   defm: Memopxi_pat<load, store, u6_2ImmPred, add, m5_0ImmPred, NegImm32,
1960                     L4_isub_memopw_io>;
1961
1962   // clrbit imm
1963   defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, and, IsNPow2_8,
1964         /*anyext*/  LogN2_8, L4_iand_memopb_io>;
1965   defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, and, IsNPow2_8,
1966         /*sext*/    LogN2_8, L4_iand_memopb_io>;
1967   defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, and, IsNPow2_8,
1968         /*zext*/    LogN2_8, L4_iand_memopb_io>;
1969   defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, and, IsNPow2_16,
1970         /*anyext*/  LogN2_16, L4_iand_memoph_io>;
1971   defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, and, IsNPow2_16,
1972         /*sext*/    LogN2_16, L4_iand_memoph_io>;
1973   defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, and, IsNPow2_16,
1974         /*zext*/    LogN2_16, L4_iand_memoph_io>;
1975   defm: Memopxi_pat<load, store, u6_2ImmPred, and, IsNPow2_32,
1976                     LogN2_32, L4_iand_memopw_io>;
1977
1978   // setbit imm
1979   defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, or, IsPow2_32,
1980         /*anyext*/  Log2_8, L4_ior_memopb_io>;
1981   defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, or, IsPow2_32,
1982         /*sext*/    Log2_8, L4_ior_memopb_io>;
1983   defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, or, IsPow2_32,
1984         /*zext*/    Log2_8, L4_ior_memopb_io>;
1985   defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, or, IsPow2_32,
1986         /*anyext*/  Log2_16, L4_ior_memoph_io>;
1987   defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, or, IsPow2_32,
1988         /*sext*/    Log2_16, L4_ior_memoph_io>;
1989   defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, or, IsPow2_32,
1990         /*zext*/    Log2_16, L4_ior_memoph_io>;
1991   defm: Memopxi_pat<load, store, u6_2ImmPred, or, IsPow2_32,
1992                     Log2_32, L4_ior_memopw_io>;
1993 }
1994
1995 def : T_CMP_pat <C4_cmpneqi,  setne,  s32_0ImmPred>;
1996 def : T_CMP_pat <C4_cmpltei,  setle,  s32_0ImmPred>;
1997 def : T_CMP_pat <C4_cmplteui, setule, u9_0ImmPred>;
1998
1999 // Map cmplt(Rs, Imm) -> !cmpgt(Rs, Imm-1).
2000 def: Pat<(i1 (setlt I32:$src1, s32_0ImmPred:$src2)),
2001          (C4_cmpltei IntRegs:$src1, (SDEC1 s32_0ImmPred:$src2))>;
2002
2003 // rs != rt -> !(rs == rt).
2004 def: Pat<(i1 (setne I32:$src1, s32_0ImmPred:$src2)),
2005          (C4_cmpneqi IntRegs:$src1, s32_0ImmPred:$src2)>;
2006
2007 // For the sequence
2008 //   zext( setult ( and(Rs, 255), u8))
2009 // Use the isdigit transformation below
2010
2011
2012 def u7_0PosImmPred : ImmLeaf<i32, [{
2013   // True if the immediate fits in an 7-bit unsigned field and
2014   // is strictly greater than 0.
2015   return Imm > 0 && isUInt<7>(Imm);
2016 }]>;
2017
2018
2019 // Generate code of the form 'C2_muxii(cmpbgtui(Rdd, C-1),0,1)'
2020 // for C code of the form r = ((c>='0') & (c<='9')) ? 1 : 0;.
2021 // The isdigit transformation relies on two 'clever' aspects:
2022 // 1) The data type is unsigned which allows us to eliminate a zero test after
2023 //    biasing the expression by 48. We are depending on the representation of
2024 //    the unsigned types, and semantics.
2025 // 2) The front end has converted <= 9 into < 10 on entry to LLVM
2026 //
2027 // For the C code:
2028 //   retval = ((c>='0') & (c<='9')) ? 1 : 0;
2029 // The code is transformed upstream of llvm into
2030 //   retval = (c-48) < 10 ? 1 : 0;
2031
2032 let AddedComplexity = 139 in
2033 def: Pat<(i32 (zext (i1 (setult (and I32:$src1, 255), u7_0PosImmPred:$src2)))),
2034          (C2_muxii (A4_cmpbgtui IntRegs:$src1, (UDEC1 imm:$src2)), 0, 1)>;
2035
2036 class Loada_pat<PatFrag Load, ValueType VT, PatFrag Addr, InstHexagon MI>
2037   : Pat<(VT (Load Addr:$addr)), (MI Addr:$addr)>;
2038
2039 class Loadam_pat<PatFrag Load, ValueType VT, PatFrag Addr, PatFrag ValueMod,
2040                  InstHexagon MI>
2041   : Pat<(VT (Load Addr:$addr)), (ValueMod (MI Addr:$addr))>;
2042
2043 class Storea_pat<PatFrag Store, PatFrag Value, PatFrag Addr, InstHexagon MI>
2044   : Pat<(Store Value:$val, Addr:$addr), (MI Addr:$addr, Value:$val)>;
2045
2046 class Stoream_pat<PatFrag Store, PatFrag Value, PatFrag Addr, PatFrag ValueMod,
2047                   InstHexagon MI>
2048   : Pat<(Store Value:$val, Addr:$addr),
2049         (MI Addr:$addr, (ValueMod Value:$val))>;
2050
2051 let AddedComplexity = 30 in {
2052   def: Storea_pat<truncstorei8,  I32, addrga, PS_storerbabs>;
2053   def: Storea_pat<truncstorei16, I32, addrga, PS_storerhabs>;
2054   def: Storea_pat<store,         I32, addrga, PS_storeriabs>;
2055   def: Storea_pat<store,         I64, addrga, PS_storerdabs>;
2056
2057   def: Stoream_pat<truncstorei8,  I64, addrga, LoReg, PS_storerbabs>;
2058   def: Stoream_pat<truncstorei16, I64, addrga, LoReg, PS_storerhabs>;
2059   def: Stoream_pat<truncstorei32, I64, addrga, LoReg, PS_storeriabs>;
2060 }
2061
2062 def: Storea_pat<SwapSt<atomic_store_8>,  I32, addrgp, S2_storerbgp>;
2063 def: Storea_pat<SwapSt<atomic_store_16>, I32, addrgp, S2_storerhgp>;
2064 def: Storea_pat<SwapSt<atomic_store_32>, I32, addrgp, S2_storerigp>;
2065 def: Storea_pat<SwapSt<atomic_store_64>, I64, addrgp, S2_storerdgp>;
2066
2067 let AddedComplexity = 100 in {
2068   def: Storea_pat<truncstorei8,  I32, addrgp, S2_storerbgp>;
2069   def: Storea_pat<truncstorei16, I32, addrgp, S2_storerhgp>;
2070   def: Storea_pat<store,         I32, addrgp, S2_storerigp>;
2071   def: Storea_pat<store,         I64, addrgp, S2_storerdgp>;
2072
2073   // Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
2074   //       to "r0 = 1; memw(#foo) = r0"
2075   let AddedComplexity = 100 in
2076   def: Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
2077            (S2_storerbgp tglobaladdr:$global, (A2_tfrsi 1))>;
2078 }
2079
2080 class LoadAbs_pats <PatFrag ldOp, InstHexagon MI, ValueType VT = i32>
2081   : Pat <(VT (ldOp (HexagonCONST32 tglobaladdr:$absaddr))),
2082          (VT (MI tglobaladdr:$absaddr))>;
2083
2084 let AddedComplexity  = 30 in {
2085   def: LoadAbs_pats <load,        PS_loadriabs>;
2086   def: LoadAbs_pats <zextloadi1,  PS_loadrubabs>;
2087   def: LoadAbs_pats <sextloadi8,  PS_loadrbabs>;
2088   def: LoadAbs_pats <extloadi8,   PS_loadrubabs>;
2089   def: LoadAbs_pats <zextloadi8,  PS_loadrubabs>;
2090   def: LoadAbs_pats <sextloadi16, PS_loadrhabs>;
2091   def: LoadAbs_pats <extloadi16,  PS_loadruhabs>;
2092   def: LoadAbs_pats <zextloadi16, PS_loadruhabs>;
2093   def: LoadAbs_pats <load,        PS_loadrdabs, i64>;
2094 }
2095
2096 let AddedComplexity  = 30 in
2097 def: Pat<(i64 (zextloadi1 (HexagonCONST32 tglobaladdr:$absaddr))),
2098          (ToZext64 (PS_loadrubabs tglobaladdr:$absaddr))>;
2099
2100 def: Loada_pat<atomic_load_8,  i32, addrgp, L2_loadrubgp>;
2101 def: Loada_pat<atomic_load_16, i32, addrgp, L2_loadruhgp>;
2102 def: Loada_pat<atomic_load_32, i32, addrgp, L2_loadrigp>;
2103 def: Loada_pat<atomic_load_64, i64, addrgp, L2_loadrdgp>;
2104
2105 def: Loadam_pat<load, i1, addrga, I32toI1, PS_loadrubabs>;
2106 def: Loadam_pat<load, i1, addrgp, I32toI1, L2_loadrubgp>;
2107
2108 def: Stoream_pat<store, I1, addrga, I1toI32, PS_storerbabs>;
2109 def: Stoream_pat<store, I1, addrgp, I1toI32, S2_storerbgp>;
2110
2111 // Map from load(globaladdress) -> mem[u][bhwd](#foo)
2112 class LoadGP_pats <PatFrag ldOp, InstHexagon MI, ValueType VT = i32>
2113   : Pat <(VT (ldOp (HexagonCONST32_GP tglobaladdr:$global))),
2114          (VT (MI tglobaladdr:$global))>;
2115
2116 let AddedComplexity = 100 in {
2117   def: LoadGP_pats <extloadi8,   L2_loadrubgp>;
2118   def: LoadGP_pats <sextloadi8,  L2_loadrbgp>;
2119   def: LoadGP_pats <zextloadi8,  L2_loadrubgp>;
2120   def: LoadGP_pats <extloadi16,  L2_loadruhgp>;
2121   def: LoadGP_pats <sextloadi16, L2_loadrhgp>;
2122   def: LoadGP_pats <zextloadi16, L2_loadruhgp>;
2123   def: LoadGP_pats <load,        L2_loadrigp>;
2124   def: LoadGP_pats <load,        L2_loadrdgp, i64>;
2125 }
2126
2127 // When the Interprocedural Global Variable optimizer realizes that a certain
2128 // global variable takes only two constant values, it shrinks the global to
2129 // a boolean. Catch those loads here in the following 3 patterns.
2130 let AddedComplexity = 100 in {
2131   def: LoadGP_pats <extloadi1, L2_loadrubgp>;
2132   def: LoadGP_pats <zextloadi1, L2_loadrubgp>;
2133 }
2134
2135 // Transfer global address into a register
2136 def: Pat<(HexagonCONST32 tglobaladdr:$Rs),      (A2_tfrsi imm:$Rs)>;
2137 def: Pat<(HexagonCONST32_GP tblockaddress:$Rs), (A2_tfrsi imm:$Rs)>;
2138 def: Pat<(HexagonCONST32_GP tglobaladdr:$Rs),   (A2_tfrsi imm:$Rs)>;
2139
2140 let AddedComplexity  = 30 in {
2141   def: Storea_pat<truncstorei8,  I32, u32_0ImmPred, PS_storerbabs>;
2142   def: Storea_pat<truncstorei16, I32, u32_0ImmPred, PS_storerhabs>;
2143   def: Storea_pat<store,         I32, u32_0ImmPred, PS_storeriabs>;
2144 }
2145
2146 let AddedComplexity  = 30 in {
2147   def: Loada_pat<load,        i32, u32_0ImmPred, PS_loadriabs>;
2148   def: Loada_pat<sextloadi8,  i32, u32_0ImmPred, PS_loadrbabs>;
2149   def: Loada_pat<zextloadi8,  i32, u32_0ImmPred, PS_loadrubabs>;
2150   def: Loada_pat<sextloadi16, i32, u32_0ImmPred, PS_loadrhabs>;
2151   def: Loada_pat<zextloadi16, i32, u32_0ImmPred, PS_loadruhabs>;
2152 }
2153
2154 // Indexed store word - global address.
2155 // memw(Rs+#u6:2)=#S8
2156 let AddedComplexity = 100 in
2157 defm: Storex_add_pat<store, addrga, u6_2ImmPred, S4_storeiri_io>;
2158
2159 // Load from a global address that has only one use in the current basic block.
2160 let AddedComplexity = 100 in {
2161   def: Loada_pat<extloadi8,   i32, addrga, PS_loadrubabs>;
2162   def: Loada_pat<sextloadi8,  i32, addrga, PS_loadrbabs>;
2163   def: Loada_pat<zextloadi8,  i32, addrga, PS_loadrubabs>;
2164
2165   def: Loada_pat<extloadi16,  i32, addrga, PS_loadruhabs>;
2166   def: Loada_pat<sextloadi16, i32, addrga, PS_loadrhabs>;
2167   def: Loada_pat<zextloadi16, i32, addrga, PS_loadruhabs>;
2168
2169   def: Loada_pat<load,        i32, addrga, PS_loadriabs>;
2170   def: Loada_pat<load,        i64, addrga, PS_loadrdabs>;
2171 }
2172
2173 // Store to a global address that has only one use in the current basic block.
2174 let AddedComplexity = 100 in {
2175   def: Storea_pat<truncstorei8,  I32, addrga, PS_storerbabs>;
2176   def: Storea_pat<truncstorei16, I32, addrga, PS_storerhabs>;
2177   def: Storea_pat<store,         I32, addrga, PS_storeriabs>;
2178   def: Storea_pat<store,         I64, addrga, PS_storerdabs>;
2179
2180   def: Stoream_pat<truncstorei32, I64, addrga, LoReg, PS_storeriabs>;
2181 }
2182
2183 // i8/i16/i32 -> i64 loads
2184 // We need a complexity of 120 here to override preceding handling of
2185 // zextload.
2186 let AddedComplexity = 120 in {
2187   def: Loadam_pat<extloadi8,   i64, addrga, ToZext64, PS_loadrubabs>;
2188   def: Loadam_pat<sextloadi8,  i64, addrga, ToSext64, PS_loadrbabs>;
2189   def: Loadam_pat<zextloadi8,  i64, addrga, ToZext64, PS_loadrubabs>;
2190
2191   def: Loadam_pat<extloadi16,  i64, addrga, ToZext64, PS_loadruhabs>;
2192   def: Loadam_pat<sextloadi16, i64, addrga, ToSext64, PS_loadrhabs>;
2193   def: Loadam_pat<zextloadi16, i64, addrga, ToZext64, PS_loadruhabs>;
2194
2195   def: Loadam_pat<extloadi32,  i64, addrga, ToZext64, PS_loadriabs>;
2196   def: Loadam_pat<sextloadi32, i64, addrga, ToSext64, PS_loadriabs>;
2197   def: Loadam_pat<zextloadi32, i64, addrga, ToZext64, PS_loadriabs>;
2198 }
2199
2200 let AddedComplexity = 100 in {
2201   def: Loada_pat<extloadi8,   i32, addrgp, PS_loadrubabs>;
2202   def: Loada_pat<sextloadi8,  i32, addrgp, PS_loadrbabs>;
2203   def: Loada_pat<zextloadi8,  i32, addrgp, PS_loadrubabs>;
2204
2205   def: Loada_pat<extloadi16,  i32, addrgp, PS_loadruhabs>;
2206   def: Loada_pat<sextloadi16, i32, addrgp, PS_loadrhabs>;
2207   def: Loada_pat<zextloadi16, i32, addrgp, PS_loadruhabs>;
2208
2209   def: Loada_pat<load,        i32, addrgp, PS_loadriabs>;
2210   def: Loada_pat<load,        i64, addrgp, PS_loadrdabs>;
2211 }
2212
2213 let AddedComplexity = 100 in {
2214   def: Storea_pat<truncstorei8,  I32, addrgp, PS_storerbabs>;
2215   def: Storea_pat<truncstorei16, I32, addrgp, PS_storerhabs>;
2216   def: Storea_pat<store,         I32, addrgp, PS_storeriabs>;
2217   def: Storea_pat<store,         I64, addrgp, PS_storerdabs>;
2218 }
2219
2220 def: Loada_pat<atomic_load_8,  i32, addrgp, PS_loadrubabs>;
2221 def: Loada_pat<atomic_load_16, i32, addrgp, PS_loadruhabs>;
2222 def: Loada_pat<atomic_load_32, i32, addrgp, PS_loadriabs>;
2223 def: Loada_pat<atomic_load_64, i64, addrgp, PS_loadrdabs>;
2224
2225 def: Storea_pat<SwapSt<atomic_store_8>,  I32, addrgp, PS_storerbabs>;
2226 def: Storea_pat<SwapSt<atomic_store_16>, I32, addrgp, PS_storerhabs>;
2227 def: Storea_pat<SwapSt<atomic_store_32>, I32, addrgp, PS_storeriabs>;
2228 def: Storea_pat<SwapSt<atomic_store_64>, I64, addrgp, PS_storerdabs>;
2229
2230 def: Pat<(or (or (or (shl (i64 (zext (and I32:$b, (i32 65535)))), (i32 16)),
2231                      (i64 (zext (i32 (and I32:$a, (i32 65535)))))),
2232                  (shl (i64 (anyext (and I32:$c, (i32 65535)))), (i32 32))),
2233              (shl (Aext64 I32:$d), (i32 48))),
2234          (A2_combinew (A2_combine_ll I32:$d, I32:$c),
2235                       (A2_combine_ll I32:$b, I32:$a))>;
2236
2237 // We need custom lowering of ISD::PREFETCH into HexagonISD::DCFETCH
2238 // because the SDNode ISD::PREFETCH has properties MayLoad and MayStore.
2239 // We don't really want either one here.
2240 def SDTHexagonDCFETCH : SDTypeProfile<0, 2, [SDTCisPtrTy<0>,SDTCisInt<1>]>;
2241 def HexagonDCFETCH : SDNode<"HexagonISD::DCFETCH", SDTHexagonDCFETCH,
2242                             [SDNPHasChain]>;
2243
2244 def: Pat<(HexagonDCFETCH IntRegs:$Rs, u11_3ImmPred:$u11_3),
2245          (Y2_dcfetchbo IntRegs:$Rs, imm:$u11_3)>;
2246 def: Pat<(HexagonDCFETCH (i32 (add IntRegs:$Rs, u11_3ImmPred:$u11_3)), (i32 0)),
2247          (Y2_dcfetchbo IntRegs:$Rs, imm:$u11_3)>;
2248
2249 def f32ImmPred : PatLeaf<(f32 fpimm:$F)>;
2250 def f64ImmPred : PatLeaf<(f64 fpimm:$F)>;
2251
2252 def ftoi : SDNodeXForm<fpimm, [{
2253   APInt I = N->getValueAPF().bitcastToAPInt();
2254   return CurDAG->getTargetConstant(I.getZExtValue(), SDLoc(N),
2255                                    MVT::getIntegerVT(I.getBitWidth()));
2256 }]>;
2257
2258
2259 def: Pat<(sra (i64 (add (sra I64:$src1, u6_0ImmPred:$src2), 1)), (i32 1)),
2260          (S2_asr_i_p_rnd I64:$src1, imm:$src2)>;
2261
2262 let AddedComplexity = 20 in {
2263   defm: Loadx_pat<load, f32, s30_2ImmPred, L2_loadri_io>;
2264   defm: Loadx_pat<load, f64, s29_3ImmPred, L2_loadrd_io>;
2265 }
2266
2267 let AddedComplexity = 60 in {
2268   defm : T_LoadAbsReg_Pat <load, L4_loadri_ur, f32>;
2269   defm : T_LoadAbsReg_Pat <load, L4_loadrd_ur, f64>;
2270 }
2271
2272 let AddedComplexity = 40 in {
2273   def: Loadxs_pat<load, f32, L4_loadri_rr>;
2274   def: Loadxs_pat<load, f64, L4_loadrd_rr>;
2275 }
2276
2277 let AddedComplexity = 20 in {
2278   def: Loadxs_simple_pat<load, f32, L4_loadri_rr>;
2279   def: Loadxs_simple_pat<load, f64, L4_loadrd_rr>;
2280 }
2281
2282 let AddedComplexity  = 80 in {
2283   def: Loada_pat<load, f32, u32_0ImmPred, PS_loadriabs>;
2284   def: Loada_pat<load, f32, addrga, PS_loadriabs>;
2285   def: Loada_pat<load, f64, addrga, PS_loadrdabs>;
2286 }
2287
2288 let AddedComplexity = 100 in {
2289   def: LoadGP_pats <load, L2_loadrigp, f32>;
2290   def: LoadGP_pats <load, L2_loadrdgp, f64>;
2291 }
2292
2293 let AddedComplexity = 20 in {
2294   defm: Storex_pat<store, F32, s30_2ImmPred, S2_storeri_io>;
2295   defm: Storex_pat<store, F64, s29_3ImmPred, S2_storerd_io>;
2296 }
2297
2298 // Simple patterns should be tried with the least priority.
2299 def: Storex_simple_pat<store, F32, S2_storeri_io>;
2300 def: Storex_simple_pat<store, F64, S2_storerd_io>;
2301
2302 let AddedComplexity = 60 in {
2303   defm : T_StoreAbsReg_Pats <S4_storeri_ur, IntRegs, f32, store>;
2304   defm : T_StoreAbsReg_Pats <S4_storerd_ur, DoubleRegs, f64, store>;
2305 }
2306
2307 let AddedComplexity = 40 in {
2308   def: Storexs_pat<store, F32, S4_storeri_rr>;
2309   def: Storexs_pat<store, F64, S4_storerd_rr>;
2310 }
2311
2312 let AddedComplexity = 20 in {
2313   def: Store_rr_pat<store, F32, S4_storeri_rr>;
2314   def: Store_rr_pat<store, F64, S4_storerd_rr>;
2315 }
2316
2317 let AddedComplexity = 80 in {
2318   def: Storea_pat<store, F32, addrga, PS_storeriabs>;
2319   def: Storea_pat<store, F64, addrga, PS_storerdabs>;
2320 }
2321
2322 let AddedComplexity = 100 in {
2323   def: Storea_pat<store, F32, addrgp, S2_storerigp>;
2324   def: Storea_pat<store, F64, addrgp, S2_storerdgp>;
2325 }
2326
2327 defm: Storex_pat<store, F32, s30_2ImmPred, S2_storeri_io>;
2328 defm: Storex_pat<store, F64, s29_3ImmPred, S2_storerd_io>;
2329 def: Storex_simple_pat<store, F32, S2_storeri_io>;
2330 def: Storex_simple_pat<store, F64, S2_storerd_io>;
2331
2332 def: Pat<(fadd F32:$src1, F32:$src2),
2333          (F2_sfadd F32:$src1, F32:$src2)>;
2334
2335 def: Pat<(fsub F32:$src1, F32:$src2),
2336          (F2_sfsub F32:$src1, F32:$src2)>;
2337
2338 def: Pat<(fmul F32:$src1, F32:$src2),
2339          (F2_sfmpy F32:$src1, F32:$src2)>;
2340
2341 let Predicates = [HasV5T] in {
2342   def: Pat<(f32 (fminnum F32:$Rs, F32:$Rt)), (F2_sfmin F32:$Rs, F32:$Rt)>;
2343   def: Pat<(f32 (fmaxnum F32:$Rs, F32:$Rt)), (F2_sfmax F32:$Rs, F32:$Rt)>;
2344 }
2345
2346 let AddedComplexity = 100, Predicates = [HasV5T] in {
2347   class SfSel12<PatFrag Cmp, InstHexagon MI>
2348     : Pat<(select (i1 (Cmp F32:$Rs, F32:$Rt)), F32:$Rs, F32:$Rt),
2349           (MI F32:$Rs, F32:$Rt)>;
2350   class SfSel21<PatFrag Cmp, InstHexagon MI>
2351     : Pat<(select (i1 (Cmp F32:$Rs, F32:$Rt)), F32:$Rt, F32:$Rs),
2352           (MI F32:$Rs, F32:$Rt)>;
2353
2354   def: SfSel12<setolt, F2_sfmin>;
2355   def: SfSel12<setole, F2_sfmin>;
2356   def: SfSel12<setogt, F2_sfmax>;
2357   def: SfSel12<setoge, F2_sfmax>;
2358   def: SfSel21<setolt, F2_sfmax>;
2359   def: SfSel21<setole, F2_sfmax>;
2360   def: SfSel21<setogt, F2_sfmin>;
2361   def: SfSel21<setoge, F2_sfmin>;
2362 }
2363
2364 class T_fcmp32_pat<PatFrag OpNode, InstHexagon MI>
2365   : Pat<(i1 (OpNode F32:$src1, F32:$src2)),
2366         (MI F32:$src1, F32:$src2)>;
2367 class T_fcmp64_pat<PatFrag OpNode, InstHexagon MI>
2368   : Pat<(i1 (OpNode F64:$src1, F64:$src2)),
2369         (MI F64:$src1, F64:$src2)>;
2370
2371 def: T_fcmp32_pat<setoge, F2_sfcmpge>;
2372 def: T_fcmp32_pat<setuo,  F2_sfcmpuo>;
2373 def: T_fcmp32_pat<setoeq, F2_sfcmpeq>;
2374 def: T_fcmp32_pat<setogt, F2_sfcmpgt>;
2375
2376 def: T_fcmp64_pat<setoge, F2_dfcmpge>;
2377 def: T_fcmp64_pat<setuo,  F2_dfcmpuo>;
2378 def: T_fcmp64_pat<setoeq, F2_dfcmpeq>;
2379 def: T_fcmp64_pat<setogt, F2_dfcmpgt>;
2380
2381 let Predicates = [HasV5T] in
2382 multiclass T_fcmp_pats<PatFrag cmpOp, InstHexagon IntMI, InstHexagon DoubleMI> {
2383   // IntRegs
2384   def: Pat<(i1 (cmpOp F32:$src1, F32:$src2)),
2385            (IntMI F32:$src1, F32:$src2)>;
2386   // DoubleRegs
2387   def: Pat<(i1 (cmpOp F64:$src1, F64:$src2)),
2388            (DoubleMI F64:$src1, F64:$src2)>;
2389 }
2390
2391 defm : T_fcmp_pats <seteq, F2_sfcmpeq, F2_dfcmpeq>;
2392 defm : T_fcmp_pats <setgt, F2_sfcmpgt, F2_dfcmpgt>;
2393 defm : T_fcmp_pats <setge, F2_sfcmpge, F2_dfcmpge>;
2394
2395 //===----------------------------------------------------------------------===//
2396 // Multiclass to define 'Def Pats' for unordered gt, ge, eq operations.
2397 //===----------------------------------------------------------------------===//
2398 let Predicates = [HasV5T] in
2399 multiclass unord_Pats <PatFrag cmpOp, InstHexagon IntMI, InstHexagon DoubleMI> {
2400   // IntRegs
2401   def: Pat<(i1 (cmpOp F32:$src1, F32:$src2)),
2402            (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
2403                   (IntMI F32:$src1, F32:$src2))>;
2404
2405   // DoubleRegs
2406   def: Pat<(i1 (cmpOp F64:$src1, F64:$src2)),
2407            (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
2408                   (DoubleMI F64:$src1, F64:$src2))>;
2409 }
2410
2411 defm : unord_Pats <setuge, F2_sfcmpge, F2_dfcmpge>;
2412 defm : unord_Pats <setugt, F2_sfcmpgt, F2_dfcmpgt>;
2413 defm : unord_Pats <setueq, F2_sfcmpeq, F2_dfcmpeq>;
2414
2415 //===----------------------------------------------------------------------===//
2416 // Multiclass to define 'Def Pats' for the following dags:
2417 // seteq(setoeq(op1, op2), 0) -> not(setoeq(op1, op2))
2418 // seteq(setoeq(op1, op2), 1) -> setoeq(op1, op2)
2419 // setne(setoeq(op1, op2), 0) -> setoeq(op1, op2)
2420 // setne(setoeq(op1, op2), 1) -> not(setoeq(op1, op2))
2421 //===----------------------------------------------------------------------===//
2422 let Predicates = [HasV5T] in
2423 multiclass eq_ordgePats <PatFrag cmpOp, InstHexagon IntMI,
2424                          InstHexagon DoubleMI> {
2425   // IntRegs
2426   def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
2427            (C2_not (IntMI F32:$src1, F32:$src2))>;
2428   def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
2429            (IntMI F32:$src1, F32:$src2)>;
2430   def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
2431            (IntMI F32:$src1, F32:$src2)>;
2432   def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
2433            (C2_not (IntMI F32:$src1, F32:$src2))>;
2434
2435   // DoubleRegs
2436   def : Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
2437             (C2_not (DoubleMI F64:$src1, F64:$src2))>;
2438   def : Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 1)),
2439             (DoubleMI F64:$src1, F64:$src2)>;
2440   def : Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
2441             (DoubleMI F64:$src1, F64:$src2)>;
2442   def : Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 1)),
2443             (C2_not (DoubleMI F64:$src1, F64:$src2))>;
2444 }
2445
2446 defm : eq_ordgePats<setoeq, F2_sfcmpeq, F2_dfcmpeq>;
2447 defm : eq_ordgePats<setoge, F2_sfcmpge, F2_dfcmpge>;
2448 defm : eq_ordgePats<setogt, F2_sfcmpgt, F2_dfcmpgt>;
2449
2450 //===----------------------------------------------------------------------===//
2451 // Multiclass to define 'Def Pats' for the following dags:
2452 // seteq(setolt(op1, op2), 0) -> not(setogt(op2, op1))
2453 // seteq(setolt(op1, op2), 1) -> setogt(op2, op1)
2454 // setne(setolt(op1, op2), 0) -> setogt(op2, op1)
2455 // setne(setolt(op1, op2), 1) -> not(setogt(op2, op1))
2456 //===----------------------------------------------------------------------===//
2457 let Predicates = [HasV5T] in
2458 multiclass eq_ordltPats <PatFrag cmpOp, InstHexagon IntMI,
2459                          InstHexagon DoubleMI> {
2460   // IntRegs
2461   def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
2462            (C2_not (IntMI F32:$src2, F32:$src1))>;
2463   def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
2464            (IntMI F32:$src2, F32:$src1)>;
2465   def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
2466            (IntMI F32:$src2, F32:$src1)>;
2467   def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
2468            (C2_not (IntMI F32:$src2, F32:$src1))>;
2469
2470   // DoubleRegs
2471   def: Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
2472            (C2_not (DoubleMI F64:$src2, F64:$src1))>;
2473   def: Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 1)),
2474            (DoubleMI F64:$src2, F64:$src1)>;
2475   def: Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
2476            (DoubleMI F64:$src2, F64:$src1)>;
2477   def: Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
2478            (C2_not (DoubleMI F64:$src2, F64:$src1))>;
2479 }
2480
2481 defm : eq_ordltPats<setole, F2_sfcmpge, F2_dfcmpge>;
2482 defm : eq_ordltPats<setolt, F2_sfcmpgt, F2_dfcmpgt>;
2483
2484
2485 // o. seto inverse of setuo. http://llvm.org/docs/LangRef.html#i_fcmp
2486 let Predicates = [HasV5T] in {
2487   def: Pat<(i1 (seto F32:$src1, F32:$src2)),
2488            (C2_not (F2_sfcmpuo F32:$src2, F32:$src1))>;
2489   def: Pat<(i1 (seto F32:$src1, f32ImmPred:$src2)),
2490            (C2_not (F2_sfcmpuo (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>;
2491   def: Pat<(i1 (seto F64:$src1, F64:$src2)),
2492            (C2_not (F2_dfcmpuo F64:$src2, F64:$src1))>;
2493   def: Pat<(i1 (seto F64:$src1, f64ImmPred:$src2)),
2494            (C2_not (F2_dfcmpuo (CONST64 (ftoi $src2)), F64:$src1))>;
2495 }
2496
2497 // Ordered lt.
2498 let Predicates = [HasV5T] in {
2499   def: Pat<(i1 (setolt F32:$src1, F32:$src2)),
2500            (F2_sfcmpgt F32:$src2, F32:$src1)>;
2501   def: Pat<(i1 (setolt F32:$src1, f32ImmPred:$src2)),
2502            (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>;
2503   def: Pat<(i1 (setolt F64:$src1, F64:$src2)),
2504            (F2_dfcmpgt F64:$src2, F64:$src1)>;
2505   def: Pat<(i1 (setolt F64:$src1, f64ImmPred:$src2)),
2506            (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1)>;
2507 }
2508
2509 // Unordered lt.
2510 let Predicates = [HasV5T] in {
2511   def: Pat<(i1 (setult F32:$src1, F32:$src2)),
2512            (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
2513                   (F2_sfcmpgt F32:$src2, F32:$src1))>;
2514   def: Pat<(i1 (setult F32:$src1, f32ImmPred:$src2)),
2515            (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))),
2516                   (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>;
2517   def: Pat<(i1 (setult F64:$src1, F64:$src2)),
2518            (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
2519                   (F2_dfcmpgt F64:$src2, F64:$src1))>;
2520   def: Pat<(i1 (setult F64:$src1, f64ImmPred:$src2)),
2521            (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))),
2522                   (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1))>;
2523 }
2524
2525 // Ordered le.
2526 let Predicates = [HasV5T] in {
2527   // rs <= rt -> rt >= rs.
2528   def: Pat<(i1 (setole F32:$src1, F32:$src2)),
2529            (F2_sfcmpge F32:$src2, F32:$src1)>;
2530   def: Pat<(i1 (setole F32:$src1, f32ImmPred:$src2)),
2531            (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>;
2532
2533   // Rss <= Rtt -> Rtt >= Rss.
2534   def: Pat<(i1 (setole F64:$src1, F64:$src2)),
2535            (F2_dfcmpge F64:$src2, F64:$src1)>;
2536   def: Pat<(i1 (setole F64:$src1, f64ImmPred:$src2)),
2537            (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1)>;
2538 }
2539
2540 // Unordered le.
2541 let Predicates = [HasV5T] in {
2542 // rs <= rt -> rt >= rs.
2543   def: Pat<(i1 (setule F32:$src1, F32:$src2)),
2544            (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
2545                   (F2_sfcmpge F32:$src2, F32:$src1))>;
2546   def: Pat<(i1 (setule F32:$src1, f32ImmPred:$src2)),
2547            (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))),
2548                   (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>;
2549   def: Pat<(i1 (setule F64:$src1, F64:$src2)),
2550            (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
2551                   (F2_dfcmpge F64:$src2, F64:$src1))>;
2552   def: Pat<(i1 (setule F64:$src1, f64ImmPred:$src2)),
2553            (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))),
2554                   (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1))>;
2555 }
2556
2557 // Ordered ne.
2558 let Predicates = [HasV5T] in {
2559   def: Pat<(i1 (setone F32:$src1, F32:$src2)),
2560            (C2_not (F2_sfcmpeq F32:$src1, F32:$src2))>;
2561   def: Pat<(i1 (setone F64:$src1, F64:$src2)),
2562            (C2_not (F2_dfcmpeq F64:$src1, F64:$src2))>;
2563   def: Pat<(i1 (setone F32:$src1, f32ImmPred:$src2)),
2564            (C2_not (F2_sfcmpeq F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))))>;
2565   def: Pat<(i1 (setone F64:$src1, f64ImmPred:$src2)),
2566            (C2_not (F2_dfcmpeq F64:$src1, (CONST64 (ftoi $src2))))>;
2567 }
2568
2569 // Unordered ne.
2570 let Predicates = [HasV5T] in {
2571   def: Pat<(i1 (setune F32:$src1, F32:$src2)),
2572            (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
2573                   (C2_not (F2_sfcmpeq F32:$src1, F32:$src2)))>;
2574   def: Pat<(i1 (setune F64:$src1, F64:$src2)),
2575            (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
2576                   (C2_not (F2_dfcmpeq F64:$src1, F64:$src2)))>;
2577   def: Pat<(i1 (setune F32:$src1, f32ImmPred:$src2)),
2578            (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))),
2579                   (C2_not (F2_sfcmpeq F32:$src1,
2580                                       (f32 (A2_tfrsi (ftoi $src2))))))>;
2581   def: Pat<(i1 (setune F64:$src1, f64ImmPred:$src2)),
2582            (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))),
2583                   (C2_not (F2_dfcmpeq F64:$src1,
2584                                       (CONST64 (ftoi $src2)))))>;
2585 }
2586
2587 // Besides set[o|u][comparions], we also need set[comparisons].
2588 let Predicates = [HasV5T] in {
2589   // lt.
2590   def: Pat<(i1 (setlt F32:$src1, F32:$src2)),
2591            (F2_sfcmpgt F32:$src2, F32:$src1)>;
2592   def: Pat<(i1 (setlt F32:$src1, f32ImmPred:$src2)),
2593            (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>;
2594   def: Pat<(i1 (setlt F64:$src1, F64:$src2)),
2595            (F2_dfcmpgt F64:$src2, F64:$src1)>;
2596   def: Pat<(i1 (setlt F64:$src1, f64ImmPred:$src2)),
2597            (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1)>;
2598
2599   // le.
2600   // rs <= rt -> rt >= rs.
2601   def: Pat<(i1 (setle F32:$src1, F32:$src2)),
2602            (F2_sfcmpge F32:$src2, F32:$src1)>;
2603   def: Pat<(i1 (setle F32:$src1, f32ImmPred:$src2)),
2604            (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>;
2605
2606   // Rss <= Rtt -> Rtt >= Rss.
2607   def: Pat<(i1 (setle F64:$src1, F64:$src2)),
2608            (F2_dfcmpge F64:$src2, F64:$src1)>;
2609   def: Pat<(i1 (setle F64:$src1, f64ImmPred:$src2)),
2610            (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1)>;
2611
2612   // ne.
2613   def: Pat<(i1 (setne F32:$src1, F32:$src2)),
2614            (C2_not (F2_sfcmpeq F32:$src1, F32:$src2))>;
2615   def: Pat<(i1 (setne F64:$src1, F64:$src2)),
2616            (C2_not (F2_dfcmpeq F64:$src1, F64:$src2))>;
2617   def: Pat<(i1 (setne F32:$src1, f32ImmPred:$src2)),
2618            (C2_not (F2_sfcmpeq F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))))>;
2619   def: Pat<(i1 (setne F64:$src1, f64ImmPred:$src2)),
2620            (C2_not (F2_dfcmpeq F64:$src1, (CONST64 (ftoi $src2))))>;
2621 }
2622
2623
2624 def: Pat<(f64 (fpextend F32:$Rs)), (F2_conv_sf2df F32:$Rs)>;
2625 def: Pat<(f32 (fpround F64:$Rs)), (F2_conv_df2sf F64:$Rs)>;
2626
2627 def: Pat<(f32 (sint_to_fp I32:$Rs)), (F2_conv_w2sf I32:$Rs)>;
2628 def: Pat<(f32 (sint_to_fp I64:$Rs)), (F2_conv_d2sf I64:$Rs)>;
2629 def: Pat<(f64 (sint_to_fp I32:$Rs)), (F2_conv_w2df I32:$Rs)>;
2630 def: Pat<(f64 (sint_to_fp I64:$Rs)), (F2_conv_d2df I64:$Rs)>;
2631
2632 def: Pat<(f32 (uint_to_fp I32:$Rs)), (F2_conv_uw2sf I32:$Rs)>;
2633 def: Pat<(f32 (uint_to_fp I64:$Rs)), (F2_conv_ud2sf I64:$Rs)>;
2634 def: Pat<(f64 (uint_to_fp I32:$Rs)), (F2_conv_uw2df I32:$Rs)>;
2635 def: Pat<(f64 (uint_to_fp I64:$Rs)), (F2_conv_ud2df I64:$Rs)>;
2636
2637 def: Pat<(i32 (fp_to_sint F32:$Rs)), (F2_conv_sf2w_chop F32:$Rs)>;
2638 def: Pat<(i32 (fp_to_sint F64:$Rs)), (F2_conv_df2w_chop F64:$Rs)>;
2639 def: Pat<(i64 (fp_to_sint F32:$Rs)), (F2_conv_sf2d_chop F32:$Rs)>;
2640 def: Pat<(i64 (fp_to_sint F64:$Rs)), (F2_conv_df2d_chop F64:$Rs)>;
2641
2642 def: Pat<(i32 (fp_to_uint F32:$Rs)), (F2_conv_sf2uw_chop F32:$Rs)>;
2643 def: Pat<(i32 (fp_to_uint F64:$Rs)), (F2_conv_df2uw_chop F64:$Rs)>;
2644 def: Pat<(i64 (fp_to_uint F32:$Rs)), (F2_conv_sf2ud_chop F32:$Rs)>;
2645 def: Pat<(i64 (fp_to_uint F64:$Rs)), (F2_conv_df2ud_chop F64:$Rs)>;
2646
2647 // Bitcast is different than [fp|sint|uint]_to_[sint|uint|fp].
2648 let Predicates = [HasV5T] in {
2649   def: Pat <(i32 (bitconvert F32:$src)), (I32:$src)>;
2650   def: Pat <(f32 (bitconvert I32:$src)), (F32:$src)>;
2651   def: Pat <(i64 (bitconvert F64:$src)), (I64:$src)>;
2652   def: Pat <(f64 (bitconvert I64:$src)), (F64:$src)>;
2653 }
2654
2655 def : Pat <(fma F32:$src2, F32:$src3, F32:$src1),
2656            (F2_sffma F32:$src1, F32:$src2, F32:$src3)>;
2657
2658 def : Pat <(fma (fneg F32:$src2), F32:$src3, F32:$src1),
2659            (F2_sffms F32:$src1, F32:$src2, F32:$src3)>;
2660
2661 def : Pat <(fma F32:$src2, (fneg F32:$src3), F32:$src1),
2662            (F2_sffms F32:$src1, F32:$src2, F32:$src3)>;
2663
2664 def: Pat<(select I1:$Pu, F32:$Rs, f32ImmPred:$imm),
2665          (C2_muxir I1:$Pu, F32:$Rs, (ftoi $imm))>,
2666     Requires<[HasV5T]>;
2667
2668 def: Pat<(select I1:$Pu, f32ImmPred:$imm, F32:$Rt),
2669          (C2_muxri I1:$Pu, (ftoi $imm), F32:$Rt)>,
2670     Requires<[HasV5T]>;
2671
2672 def: Pat<(select I1:$src1, F32:$src2, F32:$src3),
2673          (C2_mux I1:$src1, F32:$src2, F32:$src3)>,
2674      Requires<[HasV5T]>;
2675
2676 def: Pat<(select (i1 (setult F32:$src1, F32:$src2)), F32:$src3, F32:$src4),
2677          (C2_mux (F2_sfcmpgt F32:$src2, F32:$src1), F32:$src4, F32:$src3)>,
2678      Requires<[HasV5T]>;
2679
2680 def: Pat<(select I1:$src1, F64:$src2, F64:$src3),
2681          (C2_vmux I1:$src1, F64:$src2, F64:$src3)>,
2682     Requires<[HasV5T]>;
2683
2684 def: Pat<(select (i1 (setult F64:$src1, F64:$src2)), F64:$src3, F64:$src4),
2685          (C2_vmux (F2_dfcmpgt F64:$src2, F64:$src1), F64:$src3, F64:$src4)>,
2686      Requires<[HasV5T]>;
2687
2688 // Map from p0 = pnot(p0); r0 = select(p0, #i, r1)
2689 // => r0 = mux(p0, #i, r1)
2690 def: Pat<(select (not I1:$src1), f32ImmPred:$src2, F32:$src3),
2691          (C2_muxir I1:$src1, F32:$src3, (ftoi $src2))>,
2692      Requires<[HasV5T]>;
2693
2694 // Map from p0 = pnot(p0); r0 = mux(p0, r1, #i)
2695 // => r0 = mux(p0, r1, #i)
2696 def: Pat<(select (not I1:$src1), F32:$src2, f32ImmPred:$src3),
2697          (C2_muxri I1:$src1, (ftoi $src3), F32:$src2)>,
2698      Requires<[HasV5T]>;
2699
2700 def: Pat<(i32 (fp_to_sint F64:$src1)),
2701          (LoReg (F2_conv_df2d_chop F64:$src1))>,
2702      Requires<[HasV5T]>;
2703
2704 def : Pat <(fabs F32:$src1),
2705            (S2_clrbit_i F32:$src1, 31)>,
2706           Requires<[HasV5T]>;
2707
2708 def : Pat <(fneg F32:$src1),
2709            (S2_togglebit_i F32:$src1, 31)>,
2710           Requires<[HasV5T]>;
2711
2712 def: Pat<(fabs F64:$Rs),
2713          (REG_SEQUENCE DoubleRegs,
2714               (S2_clrbit_i (HiReg $Rs), 31), isub_hi,
2715               (i32 (LoReg $Rs)), isub_lo)>;
2716
2717 def: Pat<(fneg F64:$Rs),
2718          (REG_SEQUENCE DoubleRegs,
2719               (S2_togglebit_i (HiReg $Rs), 31), isub_hi,
2720               (i32 (LoReg $Rs)), isub_lo)>;
2721
2722 def alignedload : PatFrag<(ops node:$addr), (load $addr), [{
2723   return isAlignedMemNode(dyn_cast<MemSDNode>(N));
2724 }]>;
2725
2726 def unalignedload : PatFrag<(ops node:$addr), (load $addr), [{
2727   return !isAlignedMemNode(dyn_cast<MemSDNode>(N));
2728 }]>;
2729
2730 def alignedstore : PatFrag<(ops node:$val, node:$addr), (store $val, $addr), [{
2731   return isAlignedMemNode(dyn_cast<MemSDNode>(N));
2732 }]>;
2733
2734 def unalignedstore : PatFrag<(ops node:$val, node:$addr), (store $val, $addr), [{
2735   return !isAlignedMemNode(dyn_cast<MemSDNode>(N));
2736 }]>;
2737
2738
2739 multiclass vS32b_ai_pats <ValueType VTSgl, ValueType VTDbl> {
2740   // Aligned stores
2741   def : Pat<(alignedstore (VTSgl VectorRegs:$src1), IntRegs:$addr),
2742             (V6_vS32b_ai IntRegs:$addr, 0, (VTSgl VectorRegs:$src1))>,
2743             Requires<[UseHVXSgl]>;
2744   def : Pat<(unalignedstore (VTSgl VectorRegs:$src1), IntRegs:$addr),
2745             (V6_vS32Ub_ai IntRegs:$addr, 0, (VTSgl VectorRegs:$src1))>,
2746             Requires<[UseHVXSgl]>;
2747
2748   // 128B Aligned stores
2749   def : Pat<(alignedstore (VTDbl VectorRegs128B:$src1), IntRegs:$addr),
2750             (V6_vS32b_ai_128B IntRegs:$addr, 0, (VTDbl VectorRegs128B:$src1))>,
2751             Requires<[UseHVXDbl]>;
2752   def : Pat<(unalignedstore (VTDbl VectorRegs128B:$src1), IntRegs:$addr),
2753             (V6_vS32Ub_ai_128B IntRegs:$addr, 0, (VTDbl VectorRegs128B:$src1))>,
2754             Requires<[UseHVXDbl]>;
2755
2756   // Fold Add R+OFF into vector store.
2757   let AddedComplexity = 10 in {
2758     def : Pat<(alignedstore (VTSgl VectorRegs:$src1),
2759                      (add IntRegs:$src2, Iss4_6:$offset)),
2760               (V6_vS32b_ai IntRegs:$src2, Iss4_6:$offset,
2761                            (VTSgl VectorRegs:$src1))>,
2762               Requires<[UseHVXSgl]>;
2763     def : Pat<(unalignedstore (VTSgl VectorRegs:$src1),
2764                      (add IntRegs:$src2, Iss4_6:$offset)),
2765               (V6_vS32Ub_ai IntRegs:$src2, Iss4_6:$offset,
2766                            (VTSgl VectorRegs:$src1))>,
2767               Requires<[UseHVXSgl]>;
2768
2769     // Fold Add R+OFF into vector store 128B.
2770     def : Pat<(alignedstore (VTDbl VectorRegs128B:$src1),
2771                      (add IntRegs:$src2, Iss4_7:$offset)),
2772               (V6_vS32b_ai_128B IntRegs:$src2, Iss4_7:$offset,
2773                                 (VTDbl VectorRegs128B:$src1))>,
2774               Requires<[UseHVXDbl]>;
2775     def : Pat<(unalignedstore (VTDbl VectorRegs128B:$src1),
2776                      (add IntRegs:$src2, Iss4_7:$offset)),
2777               (V6_vS32Ub_ai_128B IntRegs:$src2, Iss4_7:$offset,
2778                                 (VTDbl VectorRegs128B:$src1))>,
2779               Requires<[UseHVXDbl]>;
2780   }
2781 }
2782
2783 defm : vS32b_ai_pats <v64i8,  v128i8>;
2784 defm : vS32b_ai_pats <v32i16, v64i16>;
2785 defm : vS32b_ai_pats <v16i32, v32i32>;
2786 defm : vS32b_ai_pats <v8i64,  v16i64>;
2787
2788
2789 multiclass vL32b_ai_pats <ValueType VTSgl, ValueType VTDbl> {
2790   // Aligned loads
2791   def : Pat < (VTSgl (alignedload IntRegs:$addr)),
2792               (V6_vL32b_ai IntRegs:$addr, 0) >,
2793               Requires<[UseHVXSgl]>;
2794   def : Pat < (VTSgl (unalignedload IntRegs:$addr)),
2795               (V6_vL32Ub_ai IntRegs:$addr, 0) >,
2796               Requires<[UseHVXSgl]>;
2797
2798   // 128B Load
2799   def : Pat < (VTDbl (alignedload IntRegs:$addr)),
2800               (V6_vL32b_ai_128B IntRegs:$addr, 0) >,
2801               Requires<[UseHVXDbl]>;
2802   def : Pat < (VTDbl (unalignedload IntRegs:$addr)),
2803               (V6_vL32Ub_ai_128B IntRegs:$addr, 0) >,
2804               Requires<[UseHVXDbl]>;
2805
2806   // Fold Add R+OFF into vector load.
2807   let AddedComplexity = 10 in {
2808     def : Pat<(VTDbl (alignedload (add IntRegs:$src2, Iss4_7:$offset))),
2809               (V6_vL32b_ai_128B IntRegs:$src2, Iss4_7:$offset)>,
2810                Requires<[UseHVXDbl]>;
2811     def : Pat<(VTDbl (unalignedload (add IntRegs:$src2, Iss4_7:$offset))),
2812               (V6_vL32Ub_ai_128B IntRegs:$src2, Iss4_7:$offset)>,
2813                Requires<[UseHVXDbl]>;
2814
2815     def : Pat<(VTSgl (alignedload (add IntRegs:$src2, Iss4_6:$offset))),
2816               (V6_vL32b_ai IntRegs:$src2, Iss4_6:$offset)>,
2817               Requires<[UseHVXSgl]>;
2818     def : Pat<(VTSgl (unalignedload (add IntRegs:$src2, Iss4_6:$offset))),
2819               (V6_vL32Ub_ai IntRegs:$src2, Iss4_6:$offset)>,
2820               Requires<[UseHVXSgl]>;
2821   }
2822 }
2823
2824 defm : vL32b_ai_pats <v64i8,  v128i8>;
2825 defm : vL32b_ai_pats <v32i16, v64i16>;
2826 defm : vL32b_ai_pats <v16i32, v32i32>;
2827 defm : vL32b_ai_pats <v8i64,  v16i64>;
2828
2829 multiclass STrivv_pats <ValueType VTSgl, ValueType VTDbl> {
2830   def : Pat<(alignedstore (VTSgl VecDblRegs:$src1), IntRegs:$addr),
2831             (PS_vstorerw_ai IntRegs:$addr, 0, (VTSgl VecDblRegs:$src1))>,
2832            Requires<[UseHVXSgl]>;
2833   def : Pat<(unalignedstore (VTSgl VecDblRegs:$src1), IntRegs:$addr),
2834             (PS_vstorerwu_ai IntRegs:$addr, 0, (VTSgl VecDblRegs:$src1))>,
2835            Requires<[UseHVXSgl]>;
2836
2837   def : Pat<(alignedstore (VTDbl VecDblRegs128B:$src1), IntRegs:$addr),
2838             (PS_vstorerw_ai_128B IntRegs:$addr, 0,
2839                   (VTDbl VecDblRegs128B:$src1))>,
2840             Requires<[UseHVXDbl]>;
2841   def : Pat<(unalignedstore (VTDbl VecDblRegs128B:$src1), IntRegs:$addr),
2842             (PS_vstorerwu_ai_128B IntRegs:$addr, 0,
2843                   (VTDbl VecDblRegs128B:$src1))>,
2844             Requires<[UseHVXDbl]>;
2845 }
2846
2847 defm : STrivv_pats <v128i8, v256i8>;
2848 defm : STrivv_pats <v64i16, v128i16>;
2849 defm : STrivv_pats <v32i32, v64i32>;
2850 defm : STrivv_pats <v16i64, v32i64>;
2851
2852 multiclass LDrivv_pats <ValueType VTSgl, ValueType VTDbl> {
2853   def : Pat<(VTSgl (alignedload I32:$addr)),
2854             (PS_vloadrw_ai I32:$addr, 0)>,
2855            Requires<[UseHVXSgl]>;
2856   def : Pat<(VTSgl (unalignedload I32:$addr)),
2857             (PS_vloadrwu_ai I32:$addr, 0)>,
2858            Requires<[UseHVXSgl]>;
2859
2860   def : Pat<(VTDbl (alignedload I32:$addr)),
2861             (PS_vloadrw_ai_128B I32:$addr, 0)>,
2862            Requires<[UseHVXDbl]>;
2863   def : Pat<(VTDbl (unalignedload I32:$addr)),
2864             (PS_vloadrwu_ai_128B I32:$addr, 0)>,
2865            Requires<[UseHVXDbl]>;
2866 }
2867
2868 defm : LDrivv_pats <v128i8, v256i8>;
2869 defm : LDrivv_pats <v64i16, v128i16>;
2870 defm : LDrivv_pats <v32i32, v64i32>;
2871 defm : LDrivv_pats <v16i64, v32i64>;
2872
2873 let Predicates = [HasV60T,UseHVXSgl] in {
2874   def: Pat<(select I1:$Pu, (v16i32 VectorRegs:$Vs), VectorRegs:$Vt),
2875            (PS_vselect I1:$Pu, VectorRegs:$Vs, VectorRegs:$Vt)>;
2876   def: Pat<(select I1:$Pu, (v32i32 VecDblRegs:$Vs), VecDblRegs:$Vt),
2877            (PS_wselect I1:$Pu, VecDblRegs:$Vs, VecDblRegs:$Vt)>;
2878 }
2879 let Predicates = [HasV60T,UseHVXDbl] in {
2880   def: Pat<(select I1:$Pu, (v32i32 VectorRegs128B:$Vs), VectorRegs128B:$Vt),
2881            (PS_vselect_128B I1:$Pu, VectorRegs128B:$Vs, VectorRegs128B:$Vt)>;
2882   def: Pat<(select I1:$Pu, (v64i32 VecDblRegs128B:$Vs), VecDblRegs128B:$Vt),
2883            (PS_wselect_128B I1:$Pu, VecDblRegs128B:$Vs, VecDblRegs128B:$Vt)>;
2884 }
2885
2886
2887 def SDTHexagonVCOMBINE: SDTypeProfile<1, 2, [SDTCisSameAs<1, 2>,
2888       SDTCisSubVecOfVec<1, 0>]>;
2889
2890 def HexagonVCOMBINE: SDNode<"HexagonISD::VCOMBINE", SDTHexagonVCOMBINE>;
2891
2892 def: Pat<(v32i32 (HexagonVCOMBINE (v16i32 VectorRegs:$Vs),
2893                                   (v16i32 VectorRegs:$Vt))),
2894          (V6_vcombine VectorRegs:$Vs, VectorRegs:$Vt)>,
2895          Requires<[UseHVXSgl]>;
2896 def: Pat<(v64i32 (HexagonVCOMBINE (v32i32 VecDblRegs:$Vs),
2897                                   (v32i32 VecDblRegs:$Vt))),
2898          (V6_vcombine_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
2899          Requires<[UseHVXDbl]>;
2900
2901 def SDTHexagonVPACK: SDTypeProfile<1, 3, [SDTCisSameAs<1, 2>,
2902                                           SDTCisInt<3>]>;
2903
2904 def HexagonVPACK: SDNode<"HexagonISD::VPACK", SDTHexagonVPACK>;
2905
2906 // 0 as the last argument denotes vpacke. 1 denotes vpacko
2907 def: Pat<(v64i8 (HexagonVPACK (v64i8 VectorRegs:$Vs),
2908                               (v64i8 VectorRegs:$Vt), (i32 0))),
2909          (V6_vpackeb VectorRegs:$Vs, VectorRegs:$Vt)>,
2910          Requires<[UseHVXSgl]>;
2911 def: Pat<(v64i8 (HexagonVPACK (v64i8 VectorRegs:$Vs),
2912                               (v64i8 VectorRegs:$Vt), (i32 1))),
2913          (V6_vpackob VectorRegs:$Vs, VectorRegs:$Vt)>,
2914          Requires<[UseHVXSgl]>;
2915 def: Pat<(v32i16 (HexagonVPACK (v32i16 VectorRegs:$Vs),
2916                                (v32i16 VectorRegs:$Vt), (i32 0))),
2917          (V6_vpackeh VectorRegs:$Vs, VectorRegs:$Vt)>,
2918          Requires<[UseHVXSgl]>;
2919 def: Pat<(v32i16 (HexagonVPACK (v32i16 VectorRegs:$Vs),
2920                              (v32i16 VectorRegs:$Vt), (i32 1))),
2921          (V6_vpackoh VectorRegs:$Vs, VectorRegs:$Vt)>,
2922          Requires<[UseHVXSgl]>;
2923
2924 def: Pat<(v128i8 (HexagonVPACK (v128i8 VecDblRegs:$Vs),
2925                              (v128i8 VecDblRegs:$Vt), (i32 0))),
2926          (V6_vpackeb_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
2927          Requires<[UseHVXDbl]>;
2928 def: Pat<(v128i8 (HexagonVPACK (v128i8 VecDblRegs:$Vs),
2929                              (v128i8 VecDblRegs:$Vt), (i32 1))),
2930          (V6_vpackob_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
2931          Requires<[UseHVXDbl]>;
2932 def: Pat<(v64i16 (HexagonVPACK (v64i16 VecDblRegs:$Vs),
2933                              (v64i16 VecDblRegs:$Vt), (i32 0))),
2934          (V6_vpackeh_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
2935          Requires<[UseHVXDbl]>;
2936 def: Pat<(v64i16 (HexagonVPACK (v64i16 VecDblRegs:$Vs),
2937                             (v64i16 VecDblRegs:$Vt), (i32 1))),
2938         (V6_vpackoh_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
2939         Requires<[UseHVXDbl]>;
2940
2941 def V2I1:  PatLeaf<(v2i1  PredRegs:$R)>;
2942 def V4I1:  PatLeaf<(v4i1  PredRegs:$R)>;
2943 def V8I1:  PatLeaf<(v8i1  PredRegs:$R)>;
2944 def V4I8:  PatLeaf<(v4i8  IntRegs:$R)>;
2945 def V2I16: PatLeaf<(v2i16 IntRegs:$R)>;
2946 def V8I8:  PatLeaf<(v8i8  DoubleRegs:$R)>;
2947 def V4I16: PatLeaf<(v4i16 DoubleRegs:$R)>;
2948 def V2I32: PatLeaf<(v2i32 DoubleRegs:$R)>;
2949
2950
2951 multiclass bitconvert_32<ValueType a, ValueType b> {
2952   def : Pat <(b (bitconvert (a IntRegs:$src))),
2953              (b IntRegs:$src)>;
2954   def : Pat <(a (bitconvert (b IntRegs:$src))),
2955              (a IntRegs:$src)>;
2956 }
2957
2958 multiclass bitconvert_64<ValueType a, ValueType b> {
2959   def : Pat <(b (bitconvert (a DoubleRegs:$src))),
2960              (b DoubleRegs:$src)>;
2961   def : Pat <(a (bitconvert (b DoubleRegs:$src))),
2962              (a DoubleRegs:$src)>;
2963 }
2964
2965 // Bit convert vector types to integers.
2966 defm : bitconvert_32<v4i8,  i32>;
2967 defm : bitconvert_32<v2i16, i32>;
2968 defm : bitconvert_64<v8i8,  i64>;
2969 defm : bitconvert_64<v4i16, i64>;
2970 defm : bitconvert_64<v2i32, i64>;
2971
2972 def: Pat<(sra (v4i16 DoubleRegs:$src1), u4_0ImmPred:$src2),
2973          (S2_asr_i_vh DoubleRegs:$src1, imm:$src2)>;
2974 def: Pat<(srl (v4i16 DoubleRegs:$src1), u4_0ImmPred:$src2),
2975          (S2_lsr_i_vh DoubleRegs:$src1, imm:$src2)>;
2976 def: Pat<(shl (v4i16 DoubleRegs:$src1), u4_0ImmPred:$src2),
2977          (S2_asl_i_vh DoubleRegs:$src1, imm:$src2)>;
2978
2979 def: Pat<(sra (v2i32 DoubleRegs:$src1), u5_0ImmPred:$src2),
2980          (S2_asr_i_vw DoubleRegs:$src1, imm:$src2)>;
2981 def: Pat<(srl (v2i32 DoubleRegs:$src1), u5_0ImmPred:$src2),
2982          (S2_lsr_i_vw DoubleRegs:$src1, imm:$src2)>;
2983 def: Pat<(shl (v2i32 DoubleRegs:$src1), u5_0ImmPred:$src2),
2984          (S2_asl_i_vw DoubleRegs:$src1, imm:$src2)>;
2985
2986 def : Pat<(v2i16 (add (v2i16 IntRegs:$src1), (v2i16 IntRegs:$src2))),
2987           (A2_svaddh IntRegs:$src1, IntRegs:$src2)>;
2988
2989 def : Pat<(v2i16 (sub (v2i16 IntRegs:$src1), (v2i16 IntRegs:$src2))),
2990           (A2_svsubh IntRegs:$src1, IntRegs:$src2)>;
2991
2992 def HexagonVSPLATB: SDNode<"HexagonISD::VSPLATB", SDTUnaryOp>;
2993 def HexagonVSPLATH: SDNode<"HexagonISD::VSPLATH", SDTUnaryOp>;
2994
2995 // Replicate the low 8-bits from 32-bits input register into each of the
2996 // four bytes of 32-bits destination register.
2997 def: Pat<(v4i8  (HexagonVSPLATB I32:$Rs)), (S2_vsplatrb I32:$Rs)>;
2998
2999 // Replicate the low 16-bits from 32-bits input register into each of the
3000 // four halfwords of 64-bits destination register.
3001 def: Pat<(v4i16 (HexagonVSPLATH I32:$Rs)), (S2_vsplatrh I32:$Rs)>;
3002
3003
3004 class VArith_pat <InstHexagon MI, SDNode Op, PatFrag Type>
3005   : Pat <(Op Type:$Rss, Type:$Rtt),
3006          (MI Type:$Rss, Type:$Rtt)>;
3007
3008 def: VArith_pat <A2_vaddub, add, V8I8>;
3009 def: VArith_pat <A2_vaddh,  add, V4I16>;
3010 def: VArith_pat <A2_vaddw,  add, V2I32>;
3011 def: VArith_pat <A2_vsubub, sub, V8I8>;
3012 def: VArith_pat <A2_vsubh,  sub, V4I16>;
3013 def: VArith_pat <A2_vsubw,  sub, V2I32>;
3014
3015 def: VArith_pat <A2_and,    and, V2I16>;
3016 def: VArith_pat <A2_xor,    xor, V2I16>;
3017 def: VArith_pat <A2_or,     or,  V2I16>;
3018
3019 def: VArith_pat <A2_andp,   and, V8I8>;
3020 def: VArith_pat <A2_andp,   and, V4I16>;
3021 def: VArith_pat <A2_andp,   and, V2I32>;
3022 def: VArith_pat <A2_orp,    or,  V8I8>;
3023 def: VArith_pat <A2_orp,    or,  V4I16>;
3024 def: VArith_pat <A2_orp,    or,  V2I32>;
3025 def: VArith_pat <A2_xorp,   xor, V8I8>;
3026 def: VArith_pat <A2_xorp,   xor, V4I16>;
3027 def: VArith_pat <A2_xorp,   xor, V2I32>;
3028
3029 def: Pat<(v2i32 (sra V2I32:$b, (i64 (HexagonCOMBINE (i32 u5_0ImmPred:$c),
3030                                                     (i32 u5_0ImmPred:$c))))),
3031          (S2_asr_i_vw V2I32:$b, imm:$c)>;
3032 def: Pat<(v2i32 (srl V2I32:$b, (i64 (HexagonCOMBINE (i32 u5_0ImmPred:$c),
3033                                                     (i32 u5_0ImmPred:$c))))),
3034          (S2_lsr_i_vw V2I32:$b, imm:$c)>;
3035 def: Pat<(v2i32 (shl V2I32:$b, (i64 (HexagonCOMBINE (i32 u5_0ImmPred:$c),
3036                                                     (i32 u5_0ImmPred:$c))))),
3037          (S2_asl_i_vw V2I32:$b, imm:$c)>;
3038
3039 def: Pat<(v4i16 (sra V4I16:$b, (v4i16 (HexagonVSPLATH (i32 (u4_0ImmPred:$c)))))),
3040          (S2_asr_i_vh V4I16:$b, imm:$c)>;
3041 def: Pat<(v4i16 (srl V4I16:$b, (v4i16 (HexagonVSPLATH (i32 (u4_0ImmPred:$c)))))),
3042          (S2_lsr_i_vh V4I16:$b, imm:$c)>;
3043 def: Pat<(v4i16 (shl V4I16:$b, (v4i16 (HexagonVSPLATH (i32 (u4_0ImmPred:$c)))))),
3044          (S2_asl_i_vh V4I16:$b, imm:$c)>;
3045
3046
3047 def SDTHexagon_v2i32_v2i32_i32 : SDTypeProfile<1, 2,
3048   [SDTCisSameAs<0, 1>, SDTCisVT<0, v2i32>, SDTCisInt<2>]>;
3049 def SDTHexagon_v4i16_v4i16_i32 : SDTypeProfile<1, 2,
3050   [SDTCisSameAs<0, 1>, SDTCisVT<0, v4i16>, SDTCisInt<2>]>;
3051
3052 def HexagonVSRAW: SDNode<"HexagonISD::VSRAW", SDTHexagon_v2i32_v2i32_i32>;
3053 def HexagonVSRAH: SDNode<"HexagonISD::VSRAH", SDTHexagon_v4i16_v4i16_i32>;
3054 def HexagonVSRLW: SDNode<"HexagonISD::VSRLW", SDTHexagon_v2i32_v2i32_i32>;
3055 def HexagonVSRLH: SDNode<"HexagonISD::VSRLH", SDTHexagon_v4i16_v4i16_i32>;
3056 def HexagonVSHLW: SDNode<"HexagonISD::VSHLW", SDTHexagon_v2i32_v2i32_i32>;
3057 def HexagonVSHLH: SDNode<"HexagonISD::VSHLH", SDTHexagon_v4i16_v4i16_i32>;
3058
3059 def: Pat<(v2i32 (HexagonVSRAW V2I32:$Rs, u5_0ImmPred:$u5)),
3060          (S2_asr_i_vw V2I32:$Rs, imm:$u5)>;
3061 def: Pat<(v4i16 (HexagonVSRAH V4I16:$Rs, u4_0ImmPred:$u4)),
3062          (S2_asr_i_vh V4I16:$Rs, imm:$u4)>;
3063 def: Pat<(v2i32 (HexagonVSRLW V2I32:$Rs, u5_0ImmPred:$u5)),
3064          (S2_lsr_i_vw V2I32:$Rs, imm:$u5)>;
3065 def: Pat<(v4i16 (HexagonVSRLH V4I16:$Rs, u4_0ImmPred:$u4)),
3066          (S2_lsr_i_vh V4I16:$Rs, imm:$u4)>;
3067 def: Pat<(v2i32 (HexagonVSHLW V2I32:$Rs, u5_0ImmPred:$u5)),
3068          (S2_asl_i_vw V2I32:$Rs, imm:$u5)>;
3069 def: Pat<(v4i16 (HexagonVSHLH V4I16:$Rs, u4_0ImmPred:$u4)),
3070          (S2_asl_i_vh V4I16:$Rs, imm:$u4)>;
3071
3072 class vshift_rr_pat<InstHexagon MI, SDNode Op, PatFrag Value>
3073   : Pat <(Op Value:$Rs, I32:$Rt),
3074          (MI Value:$Rs, I32:$Rt)>;
3075
3076 def: vshift_rr_pat <S2_asr_r_vw, HexagonVSRAW, V2I32>;
3077 def: vshift_rr_pat <S2_asr_r_vh, HexagonVSRAH, V4I16>;
3078 def: vshift_rr_pat <S2_lsr_r_vw, HexagonVSRLW, V2I32>;
3079 def: vshift_rr_pat <S2_lsr_r_vh, HexagonVSRLH, V4I16>;
3080 def: vshift_rr_pat <S2_asl_r_vw, HexagonVSHLW, V2I32>;
3081 def: vshift_rr_pat <S2_asl_r_vh, HexagonVSHLH, V4I16>;
3082
3083
3084 def SDTHexagonVecCompare_v8i8 : SDTypeProfile<1, 2,
3085   [SDTCisSameAs<1, 2>, SDTCisVT<0, i1>, SDTCisVT<1, v8i8>]>;
3086 def SDTHexagonVecCompare_v4i16 : SDTypeProfile<1, 2,
3087   [SDTCisSameAs<1, 2>, SDTCisVT<0, i1>, SDTCisVT<1, v4i16>]>;
3088 def SDTHexagonVecCompare_v2i32 : SDTypeProfile<1, 2,
3089   [SDTCisSameAs<1, 2>, SDTCisVT<0, i1>, SDTCisVT<1, v2i32>]>;
3090
3091 def HexagonVCMPBEQ:  SDNode<"HexagonISD::VCMPBEQ",  SDTHexagonVecCompare_v8i8>;
3092 def HexagonVCMPBGT:  SDNode<"HexagonISD::VCMPBGT",  SDTHexagonVecCompare_v8i8>;
3093 def HexagonVCMPBGTU: SDNode<"HexagonISD::VCMPBGTU", SDTHexagonVecCompare_v8i8>;
3094 def HexagonVCMPHEQ:  SDNode<"HexagonISD::VCMPHEQ",  SDTHexagonVecCompare_v4i16>;
3095 def HexagonVCMPHGT:  SDNode<"HexagonISD::VCMPHGT",  SDTHexagonVecCompare_v4i16>;
3096 def HexagonVCMPHGTU: SDNode<"HexagonISD::VCMPHGTU", SDTHexagonVecCompare_v4i16>;
3097 def HexagonVCMPWEQ:  SDNode<"HexagonISD::VCMPWEQ",  SDTHexagonVecCompare_v2i32>;
3098 def HexagonVCMPWGT:  SDNode<"HexagonISD::VCMPWGT",  SDTHexagonVecCompare_v2i32>;
3099 def HexagonVCMPWGTU: SDNode<"HexagonISD::VCMPWGTU", SDTHexagonVecCompare_v2i32>;
3100
3101
3102 class vcmp_i1_pat<InstHexagon MI, SDNode Op, PatFrag Value>
3103   : Pat <(i1 (Op Value:$Rs, Value:$Rt)),
3104          (MI Value:$Rs, Value:$Rt)>;
3105
3106 def: vcmp_i1_pat<A2_vcmpbeq,  HexagonVCMPBEQ,  V8I8>;
3107 def: vcmp_i1_pat<A4_vcmpbgt,  HexagonVCMPBGT,  V8I8>;
3108 def: vcmp_i1_pat<A2_vcmpbgtu, HexagonVCMPBGTU, V8I8>;
3109
3110 def: vcmp_i1_pat<A2_vcmpheq,  HexagonVCMPHEQ,  V4I16>;
3111 def: vcmp_i1_pat<A2_vcmphgt,  HexagonVCMPHGT,  V4I16>;
3112 def: vcmp_i1_pat<A2_vcmphgtu, HexagonVCMPHGTU, V4I16>;
3113
3114 def: vcmp_i1_pat<A2_vcmpweq,  HexagonVCMPWEQ,  V2I32>;
3115 def: vcmp_i1_pat<A2_vcmpwgt,  HexagonVCMPWGT,  V2I32>;
3116 def: vcmp_i1_pat<A2_vcmpwgtu, HexagonVCMPWGTU, V2I32>;
3117
3118
3119 class vcmp_vi1_pat<InstHexagon MI, PatFrag Op, PatFrag InVal, ValueType OutTy>
3120   : Pat <(OutTy (Op InVal:$Rs, InVal:$Rt)),
3121          (MI InVal:$Rs, InVal:$Rt)>;
3122
3123 def: vcmp_vi1_pat<A2_vcmpweq,  seteq,  V2I32, v2i1>;
3124 def: vcmp_vi1_pat<A2_vcmpwgt,  setgt,  V2I32, v2i1>;
3125 def: vcmp_vi1_pat<A2_vcmpwgtu, setugt, V2I32, v2i1>;
3126
3127 def: vcmp_vi1_pat<A2_vcmpheq,  seteq,  V4I16, v4i1>;
3128 def: vcmp_vi1_pat<A2_vcmphgt,  setgt,  V4I16, v4i1>;
3129 def: vcmp_vi1_pat<A2_vcmphgtu, setugt, V4I16, v4i1>;
3130
3131 def: Pat<(mul V2I32:$Rs, V2I32:$Rt),
3132          (PS_vmulw DoubleRegs:$Rs, DoubleRegs:$Rt)>;
3133 def: Pat<(add V2I32:$Rx, (mul V2I32:$Rs, V2I32:$Rt)),
3134          (PS_vmulw_acc DoubleRegs:$Rx, DoubleRegs:$Rs, DoubleRegs:$Rt)>;
3135
3136
3137 // Adds two v4i8: Hexagon does not have an insn for this one, so we
3138 // use the double add v8i8, and use only the low part of the result.
3139 def: Pat<(v4i8 (add (v4i8 IntRegs:$Rs), (v4i8 IntRegs:$Rt))),
3140          (LoReg (A2_vaddub (ToZext64 $Rs), (ToZext64 $Rt)))>;
3141
3142 // Subtract two v4i8: Hexagon does not have an insn for this one, so we
3143 // use the double sub v8i8, and use only the low part of the result.
3144 def: Pat<(v4i8 (sub (v4i8 IntRegs:$Rs), (v4i8 IntRegs:$Rt))),
3145          (LoReg (A2_vsubub (ToZext64 $Rs), (ToZext64 $Rt)))>;
3146
3147 //
3148 // No 32 bit vector mux.
3149 //
3150 def: Pat<(v4i8 (select I1:$Pu, V4I8:$Rs, V4I8:$Rt)),
3151          (LoReg (C2_vmux I1:$Pu, (ToZext64 $Rs), (ToZext64 $Rt)))>;
3152 def: Pat<(v2i16 (select I1:$Pu, V2I16:$Rs, V2I16:$Rt)),
3153          (LoReg (C2_vmux I1:$Pu, (ToZext64 $Rs), (ToZext64 $Rt)))>;
3154
3155 //
3156 // 64-bit vector mux.
3157 //
3158 def: Pat<(v8i8 (vselect V8I1:$Pu, V8I8:$Rs, V8I8:$Rt)),
3159          (C2_vmux V8I1:$Pu, V8I8:$Rs, V8I8:$Rt)>;
3160 def: Pat<(v4i16 (vselect V4I1:$Pu, V4I16:$Rs, V4I16:$Rt)),
3161          (C2_vmux V4I1:$Pu, V4I16:$Rs, V4I16:$Rt)>;
3162 def: Pat<(v2i32 (vselect V2I1:$Pu, V2I32:$Rs, V2I32:$Rt)),
3163          (C2_vmux V2I1:$Pu, V2I32:$Rs, V2I32:$Rt)>;
3164
3165 //
3166 // No 32 bit vector compare.
3167 //
3168 def: Pat<(i1 (seteq V4I8:$Rs, V4I8:$Rt)),
3169          (A2_vcmpbeq (ToZext64 $Rs), (ToZext64 $Rt))>;
3170 def: Pat<(i1 (setgt V4I8:$Rs, V4I8:$Rt)),
3171          (A4_vcmpbgt (ToZext64 $Rs), (ToZext64 $Rt))>;
3172 def: Pat<(i1 (setugt V4I8:$Rs, V4I8:$Rt)),
3173          (A2_vcmpbgtu (ToZext64 $Rs), (ToZext64 $Rt))>;
3174
3175 def: Pat<(i1 (seteq V2I16:$Rs, V2I16:$Rt)),
3176          (A2_vcmpheq (ToZext64 $Rs), (ToZext64 $Rt))>;
3177 def: Pat<(i1 (setgt V2I16:$Rs, V2I16:$Rt)),
3178          (A2_vcmphgt (ToZext64 $Rs), (ToZext64 $Rt))>;
3179 def: Pat<(i1 (setugt V2I16:$Rs, V2I16:$Rt)),
3180          (A2_vcmphgtu (ToZext64 $Rs), (ToZext64 $Rt))>;
3181
3182
3183 class InvertCmp_pat<InstHexagon InvMI, PatFrag CmpOp, PatFrag Value,
3184                     ValueType CmpTy>
3185   : Pat<(CmpTy (CmpOp Value:$Rs, Value:$Rt)),
3186         (InvMI Value:$Rt, Value:$Rs)>;
3187
3188 // Map from a compare operation to the corresponding instruction with the
3189 // order of operands reversed, e.g.  x > y --> cmp.lt(y,x).
3190 def: InvertCmp_pat<A4_vcmpbgt,  setlt,  V8I8,  i1>;
3191 def: InvertCmp_pat<A4_vcmpbgt,  setlt,  V8I8,  v8i1>;
3192 def: InvertCmp_pat<A2_vcmphgt,  setlt,  V4I16, i1>;
3193 def: InvertCmp_pat<A2_vcmphgt,  setlt,  V4I16, v4i1>;
3194 def: InvertCmp_pat<A2_vcmpwgt,  setlt,  V2I32, i1>;
3195 def: InvertCmp_pat<A2_vcmpwgt,  setlt,  V2I32, v2i1>;
3196
3197 def: InvertCmp_pat<A2_vcmpbgtu, setult, V8I8,  i1>;
3198 def: InvertCmp_pat<A2_vcmpbgtu, setult, V8I8,  v8i1>;
3199 def: InvertCmp_pat<A2_vcmphgtu, setult, V4I16, i1>;
3200 def: InvertCmp_pat<A2_vcmphgtu, setult, V4I16, v4i1>;
3201 def: InvertCmp_pat<A2_vcmpwgtu, setult, V2I32, i1>;
3202 def: InvertCmp_pat<A2_vcmpwgtu, setult, V2I32, v2i1>;
3203
3204 // Map from vcmpne(Rss) -> !vcmpew(Rss).
3205 // rs != rt -> !(rs == rt).
3206 def: Pat<(v2i1 (setne V2I32:$Rs, V2I32:$Rt)),
3207          (C2_not (v2i1 (A2_vcmpbeq V2I32:$Rs, V2I32:$Rt)))>;
3208
3209
3210 // Truncate: from vector B copy all 'E'ven 'B'yte elements:
3211 // A[0] = B[0];  A[1] = B[2];  A[2] = B[4];  A[3] = B[6];
3212 def: Pat<(v4i8 (trunc V4I16:$Rs)),
3213          (S2_vtrunehb V4I16:$Rs)>;
3214
3215 // Truncate: from vector B copy all 'O'dd 'B'yte elements:
3216 // A[0] = B[1];  A[1] = B[3];  A[2] = B[5];  A[3] = B[7];
3217 // S2_vtrunohb
3218
3219 // Truncate: from vectors B and C copy all 'E'ven 'H'alf-word elements:
3220 // A[0] = B[0];  A[1] = B[2];  A[2] = C[0];  A[3] = C[2];
3221 // S2_vtruneh
3222
3223 def: Pat<(v2i16 (trunc V2I32:$Rs)),
3224          (LoReg (S2_packhl (HiReg $Rs), (LoReg $Rs)))>;
3225
3226
3227 def HexagonVSXTBH : SDNode<"HexagonISD::VSXTBH", SDTUnaryOp>;
3228 def HexagonVSXTBW : SDNode<"HexagonISD::VSXTBW", SDTUnaryOp>;
3229
3230 def: Pat<(i64 (HexagonVSXTBH I32:$Rs)), (S2_vsxtbh I32:$Rs)>;
3231 def: Pat<(i64 (HexagonVSXTBW I32:$Rs)), (S2_vsxthw I32:$Rs)>;
3232
3233 def: Pat<(v4i16 (zext   V4I8:$Rs)),  (S2_vzxtbh V4I8:$Rs)>;
3234 def: Pat<(v2i32 (zext   V2I16:$Rs)), (S2_vzxthw V2I16:$Rs)>;
3235 def: Pat<(v4i16 (anyext V4I8:$Rs)),  (S2_vzxtbh V4I8:$Rs)>;
3236 def: Pat<(v2i32 (anyext V2I16:$Rs)), (S2_vzxthw V2I16:$Rs)>;
3237 def: Pat<(v4i16 (sext   V4I8:$Rs)),  (S2_vsxtbh V4I8:$Rs)>;
3238 def: Pat<(v2i32 (sext   V2I16:$Rs)), (S2_vsxthw V2I16:$Rs)>;
3239
3240 // Sign extends a v2i8 into a v2i32.
3241 def: Pat<(v2i32 (sext_inreg V2I32:$Rs, v2i8)),
3242          (A2_combinew (A2_sxtb (HiReg $Rs)), (A2_sxtb (LoReg $Rs)))>;
3243
3244 // Sign extends a v2i16 into a v2i32.
3245 def: Pat<(v2i32 (sext_inreg V2I32:$Rs, v2i16)),
3246          (A2_combinew (A2_sxth (HiReg $Rs)), (A2_sxth (LoReg $Rs)))>;
3247
3248
3249 // Multiplies two v2i16 and returns a v2i32.  We are using here the
3250 // saturating multiply, as hexagon does not provide a non saturating
3251 // vector multiply, and saturation does not impact the result that is
3252 // in double precision of the operands.
3253
3254 // Multiplies two v2i16 vectors: as Hexagon does not have a multiply
3255 // with the C semantics for this one, this pattern uses the half word
3256 // multiply vmpyh that takes two v2i16 and returns a v2i32.  This is
3257 // then truncated to fit this back into a v2i16 and to simulate the
3258 // wrap around semantics for unsigned in C.
3259 def vmpyh: OutPatFrag<(ops node:$Rs, node:$Rt),
3260                       (M2_vmpy2s_s0 (i32 $Rs), (i32 $Rt))>;
3261
3262 def: Pat<(v2i16 (mul V2I16:$Rs, V2I16:$Rt)),
3263          (LoReg (S2_vtrunewh (A2_combineii 0, 0),
3264                              (vmpyh V2I16:$Rs, V2I16:$Rt)))>;
3265
3266 // Multiplies two v4i16 vectors.
3267 def: Pat<(v4i16 (mul V4I16:$Rs, V4I16:$Rt)),
3268          (S2_vtrunewh (vmpyh (HiReg $Rs), (HiReg $Rt)),
3269                       (vmpyh (LoReg $Rs), (LoReg $Rt)))>;
3270
3271 def VMPYB_no_V5: OutPatFrag<(ops node:$Rs, node:$Rt),
3272   (S2_vtrunewh (vmpyh (HiReg (S2_vsxtbh $Rs)), (HiReg (S2_vsxtbh $Rt))),
3273                (vmpyh (LoReg (S2_vsxtbh $Rs)), (LoReg (S2_vsxtbh $Rt))))>;
3274
3275 // Multiplies two v4i8 vectors.
3276 def: Pat<(v4i8 (mul V4I8:$Rs, V4I8:$Rt)),
3277          (S2_vtrunehb (M5_vmpybsu V4I8:$Rs, V4I8:$Rt))>,
3278      Requires<[HasV5T]>;
3279
3280 def: Pat<(v4i8 (mul V4I8:$Rs, V4I8:$Rt)),
3281          (S2_vtrunehb (VMPYB_no_V5 V4I8:$Rs, V4I8:$Rt))>;
3282
3283 // Multiplies two v8i8 vectors.
3284 def: Pat<(v8i8 (mul V8I8:$Rs, V8I8:$Rt)),
3285          (A2_combinew (S2_vtrunehb (M5_vmpybsu (HiReg $Rs), (HiReg $Rt))),
3286                       (S2_vtrunehb (M5_vmpybsu (LoReg $Rs), (LoReg $Rt))))>,
3287      Requires<[HasV5T]>;
3288
3289 def: Pat<(v8i8 (mul V8I8:$Rs, V8I8:$Rt)),
3290          (A2_combinew (S2_vtrunehb (VMPYB_no_V5 (HiReg $Rs), (HiReg $Rt))),
3291                       (S2_vtrunehb (VMPYB_no_V5 (LoReg $Rs), (LoReg $Rt))))>;
3292
3293 def SDTHexagonBinOp64 : SDTypeProfile<1, 2,
3294   [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64>]>;
3295
3296 def HexagonSHUFFEB: SDNode<"HexagonISD::SHUFFEB", SDTHexagonBinOp64>;
3297 def HexagonSHUFFEH: SDNode<"HexagonISD::SHUFFEH", SDTHexagonBinOp64>;
3298 def HexagonSHUFFOB: SDNode<"HexagonISD::SHUFFOB", SDTHexagonBinOp64>;
3299 def HexagonSHUFFOH: SDNode<"HexagonISD::SHUFFOH", SDTHexagonBinOp64>;
3300
3301 class ShufflePat<InstHexagon MI, SDNode Op>
3302   : Pat<(i64 (Op DoubleRegs:$src1, DoubleRegs:$src2)),
3303         (i64 (MI DoubleRegs:$src1, DoubleRegs:$src2))>;
3304
3305 // Shuffles even bytes for i=0..3: A[2*i].b = C[2*i].b; A[2*i+1].b = B[2*i].b
3306 def: ShufflePat<S2_shuffeb, HexagonSHUFFEB>;
3307
3308 // Shuffles odd bytes for i=0..3: A[2*i].b = C[2*i+1].b; A[2*i+1].b = B[2*i+1].b
3309 def: ShufflePat<S2_shuffob, HexagonSHUFFOB>;
3310
3311 // Shuffles even half for i=0,1: A[2*i].h = C[2*i].h; A[2*i+1].h = B[2*i].h
3312 def: ShufflePat<S2_shuffeh, HexagonSHUFFEH>;
3313
3314 // Shuffles odd half for i=0,1: A[2*i].h = C[2*i+1].h; A[2*i+1].h = B[2*i+1].h
3315 def: ShufflePat<S2_shuffoh, HexagonSHUFFOH>;
3316
3317
3318 // Truncated store from v4i16 to v4i8.
3319 def truncstorev4i8: PatFrag<(ops node:$val, node:$ptr),
3320                             (truncstore node:$val, node:$ptr),
3321     [{ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v4i8; }]>;
3322
3323 // Truncated store from v2i32 to v2i16.
3324 def truncstorev2i16: PatFrag<(ops node:$val, node:$ptr),
3325                              (truncstore node:$val, node:$ptr),
3326     [{ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v2i16; }]>;
3327
3328 def: Pat<(truncstorev2i16 V2I32:$Rs, I32:$Rt),
3329          (S2_storeri_io I32:$Rt, 0, (LoReg (S2_packhl (HiReg $Rs),
3330                                                       (LoReg $Rs))))>;
3331
3332 def: Pat<(truncstorev4i8 V4I16:$Rs, I32:$Rt),
3333          (S2_storeri_io I32:$Rt, 0, (S2_vtrunehb V4I16:$Rs))>;
3334
3335
3336 // Zero and sign extended load from v2i8 into v2i16.
3337 def zextloadv2i8: PatFrag<(ops node:$ptr), (zextload node:$ptr),
3338     [{ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v2i8; }]>;
3339
3340 def sextloadv2i8: PatFrag<(ops node:$ptr), (sextload node:$ptr),
3341     [{ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v2i8; }]>;
3342
3343 def: Pat<(v2i16 (zextloadv2i8 I32:$Rs)),
3344          (LoReg (v4i16 (S2_vzxtbh (L2_loadruh_io I32:$Rs, 0))))>;
3345
3346 def: Pat<(v2i16 (sextloadv2i8 I32:$Rs)),
3347          (LoReg (v4i16 (S2_vsxtbh (L2_loadrh_io I32:$Rs, 0))))>;
3348
3349 def: Pat<(v2i32 (zextloadv2i8 I32:$Rs)),
3350          (S2_vzxthw (LoReg (v4i16 (S2_vzxtbh (L2_loadruh_io I32:$Rs, 0)))))>;
3351
3352 def: Pat<(v2i32 (sextloadv2i8 I32:$Rs)),
3353          (S2_vsxthw (LoReg (v4i16 (S2_vsxtbh (L2_loadrh_io I32:$Rs, 0)))))>;
3354
3355
3356 // Read cycle counter.
3357 //
3358 def SDTInt64Leaf: SDTypeProfile<1, 0, [SDTCisVT<0, i64>]>;
3359 def HexagonREADCYCLE: SDNode<"HexagonISD::READCYCLE", SDTInt64Leaf,
3360   [SDNPHasChain]>;
3361
3362 def: Pat<(HexagonREADCYCLE), (A4_tfrcpp UPCYCLE)>;