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