blob: 70ed123bc8981fb411a0172e1c2751f9191f122a [file] [log] [blame]
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001// Pattern fragment that combines the value type and the register class
2// into a single parameter.
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003
4// Pattern fragments to extract the low and high subregisters from a
5// 64-bit value.
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00006def LoReg: OutPatFrag<(ops node:$Rs), (EXTRACT_SUBREG (i64 $Rs), isub_lo)>;
7def HiReg: OutPatFrag<(ops node:$Rs), (EXTRACT_SUBREG (i64 $Rs), isub_hi)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00008
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +00009def IsOrAdd: PatFrag<(ops node:$Addr, node:$off),
10 (or node:$Addr, node:$off), [{ return isOrEquivalentToAdd(N); }]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +000011
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +000012def Iss4_6 : PatLeaf<(i32 imm), [{
13 int32_t V = N->getSExtValue();
14 return isShiftedInt<4,6>(V);
15}]>;
16
17def Iss4_7 : PatLeaf<(i32 imm), [{
18 int32_t V = N->getSExtValue();
19 return isShiftedInt<4,7>(V);
20}]>;
21
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +000022def IsPow2_32 : PatLeaf<(i32 imm), [{
23 uint32_t V = N->getZExtValue();
24 return isPowerOf2_32(V);
Krzysztof Parzyszek2839b292016-11-05 21:44:50 +000025}]>;
26
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +000027def IsPow2_64 : PatLeaf<(i64 imm), [{
28 uint64_t V = N->getZExtValue();
29 return isPowerOf2_64(V);
30}]>;
31
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +000032def IsNPow2_32 : PatLeaf<(i32 imm), [{
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +000033 uint32_t NV = ~N->getZExtValue();
34 return isPowerOf2_32(NV);
35}]>;
36
37def IsPow2_64L : PatLeaf<(i64 imm), [{
38 uint64_t V = N->getZExtValue();
39 return isPowerOf2_64(V) && Log2_64(V) < 32;
40}]>;
41
42def IsPow2_64H : PatLeaf<(i64 imm), [{
43 uint64_t V = N->getZExtValue();
44 return isPowerOf2_64(V) && Log2_64(V) >= 32;
45}]>;
46
47def IsNPow2_64L : PatLeaf<(i64 imm), [{
48 uint64_t NV = ~N->getZExtValue();
49 return isPowerOf2_64(NV) && Log2_64(NV) < 32;
50}]>;
51
52def IsNPow2_64H : PatLeaf<(i64 imm), [{
53 uint64_t NV = ~N->getZExtValue();
54 return isPowerOf2_64(NV) && Log2_64(NV) >= 32;
Krzysztof Parzyszek2839b292016-11-05 21:44:50 +000055}]>;
56
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +000057def SDEC1 : SDNodeXForm<imm, [{
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +000058 int32_t V = N->getSExtValue();
59 return CurDAG->getTargetConstant(V-1, SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +000060}]>;
61
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +000062def UDEC1 : SDNodeXForm<imm, [{
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +000063 uint32_t V = N->getZExtValue();
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +000064 assert(V >= 1);
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +000065 return CurDAG->getTargetConstant(V-1, SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +000066}]>;
67
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +000068def UDEC32 : SDNodeXForm<imm, [{
69 uint32_t V = N->getZExtValue();
70 assert(V >= 32);
71 return CurDAG->getTargetConstant(V-32, SDLoc(N), MVT::i32);
72}]>;
73
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +000074def Log2_32 : SDNodeXForm<imm, [{
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +000075 uint32_t V = N->getZExtValue();
76 return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32);
77}]>;
78
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +000079def Log2_64 : SDNodeXForm<imm, [{
80 uint64_t V = N->getZExtValue();
81 return CurDAG->getTargetConstant(Log2_64(V), SDLoc(N), MVT::i32);
82}]>;
83
84def LogN2_32 : SDNodeXForm<imm, [{
85 uint32_t NV = ~N->getZExtValue();
86 return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32);
87}]>;
88
89def LogN2_64 : SDNodeXForm<imm, [{
90 uint64_t NV = ~N->getZExtValue();
91 return CurDAG->getTargetConstant(Log2_64(NV), SDLoc(N), MVT::i32);
92}]>;
93
Krzysztof Parzyszekf2086812017-02-28 22:37:01 +000094def ToZext64: OutPatFrag<(ops node:$Rs),
95 (i64 (A4_combineir 0, (i32 $Rs)))>;
96def ToSext64: OutPatFrag<(ops node:$Rs),
97 (i64 (A2_sxtw (i32 $Rs)))>;
98
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +000099
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000100class T_CMP_pat <InstHexagon MI, PatFrag OpNode, PatLeaf ImmPred>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000101 : Pat<(i1 (OpNode I32:$src1, ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000102 (MI IntRegs:$src1, ImmPred:$src2)>;
103
104def : T_CMP_pat <C2_cmpeqi, seteq, s10_0ImmPred>;
105def : T_CMP_pat <C2_cmpgti, setgt, s10_0ImmPred>;
106def : T_CMP_pat <C2_cmpgtui, setugt, u9_0ImmPred>;
107
108def SDTHexagonI64I32I32 : SDTypeProfile<1, 2,
109 [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
110
111def HexagonCOMBINE : SDNode<"HexagonISD::COMBINE", SDTHexagonI64I32I32>;
112def HexagonPACKHL : SDNode<"HexagonISD::PACKHL", SDTHexagonI64I32I32>;
113
114// Pats for instruction selection.
115class BinOp32_pat<SDNode Op, InstHexagon MI, ValueType ResT>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000116 : Pat<(ResT (Op I32:$Rs, I32:$Rt)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000117 (ResT (MI IntRegs:$Rs, IntRegs:$Rt))>;
118
119def: BinOp32_pat<add, A2_add, i32>;
120def: BinOp32_pat<and, A2_and, i32>;
121def: BinOp32_pat<or, A2_or, i32>;
122def: BinOp32_pat<sub, A2_sub, i32>;
123def: BinOp32_pat<xor, A2_xor, i32>;
124
125def: BinOp32_pat<HexagonCOMBINE, A2_combinew, i64>;
126def: BinOp32_pat<HexagonPACKHL, S2_packhl, i64>;
127
128// Patfrag to convert the usual comparison patfrags (e.g. setlt) to ones
129// that reverse the order of the operands.
130class RevCmp<PatFrag F> : PatFrag<(ops node:$rhs, node:$lhs), F.Fragment>;
131
132// Pats for compares. They use PatFrags as operands, not SDNodes,
133// since seteq/setgt/etc. are defined as ParFrags.
134class T_cmp32_rr_pat<InstHexagon MI, PatFrag Op, ValueType VT>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000135 : Pat<(VT (Op I32:$Rs, I32:$Rt)),
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000136 (MI IntRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000137
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000138def: T_cmp32_rr_pat<C2_cmpeq, seteq, i1>;
139def: T_cmp32_rr_pat<C2_cmpgt, setgt, i1>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000140def: T_cmp32_rr_pat<C2_cmpgtu, setugt, i1>;
141
142def: T_cmp32_rr_pat<C2_cmpgt, RevCmp<setlt>, i1>;
143def: T_cmp32_rr_pat<C2_cmpgtu, RevCmp<setult>, i1>;
144
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000145def: Pat<(select I1:$Pu, I32:$Rs, I32:$Rt),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000146 (C2_mux PredRegs:$Pu, IntRegs:$Rs, IntRegs:$Rt)>;
147
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000148def: Pat<(add I32:$Rs, s32_0ImmPred:$s16),
149 (A2_addi I32:$Rs, imm:$s16)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000150
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000151def: Pat<(or I32:$Rs, s32_0ImmPred:$s10),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000152 (A2_orir IntRegs:$Rs, imm:$s10)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000153def: Pat<(and I32:$Rs, s32_0ImmPred:$s10),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000154 (A2_andir IntRegs:$Rs, imm:$s10)>;
155
156def: Pat<(sub s32_0ImmPred:$s10, IntRegs:$Rs),
157 (A2_subri imm:$s10, IntRegs:$Rs)>;
158
159// Rd = not(Rs) gets mapped to Rd=sub(#-1, Rs).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000160def: Pat<(not I32:$src1),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000161 (A2_subri -1, IntRegs:$src1)>;
162
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000163def TruncI64ToI32: SDNodeXForm<imm, [{
164 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32);
165}]>;
166
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000167def: Pat<(s32_0ImmPred:$s16), (A2_tfrsi imm:$s16)>;
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000168def: Pat<(s8_0Imm64Pred:$s8), (A2_tfrpi (TruncI64ToI32 $s8))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000169
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000170def : Pat<(select I1:$Pu, s32_0ImmPred:$s8, I32:$Rs),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000171 (C2_muxri I1:$Pu, imm:$s8, I32:$Rs)>;
172
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000173def : Pat<(select I1:$Pu, I32:$Rs, s32_0ImmPred:$s8),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000174 (C2_muxir I1:$Pu, I32:$Rs, imm:$s8)>;
175
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000176def : Pat<(select I1:$Pu, s32_0ImmPred:$s8, s8_0ImmPred:$S8),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000177 (C2_muxii I1:$Pu, imm:$s8, imm:$S8)>;
178
179def: Pat<(shl I32:$src1, (i32 16)), (A2_aslh I32:$src1)>;
180def: Pat<(sra I32:$src1, (i32 16)), (A2_asrh I32:$src1)>;
181def: Pat<(sext_inreg I32:$src1, i8), (A2_sxtb I32:$src1)>;
182def: Pat<(sext_inreg I32:$src1, i16), (A2_sxth I32:$src1)>;
183
184class T_vcmp_pat<InstHexagon MI, PatFrag Op, ValueType T>
185 : Pat<(i1 (Op (T DoubleRegs:$Rss), (T DoubleRegs:$Rtt))),
186 (i1 (MI DoubleRegs:$Rss, DoubleRegs:$Rtt))>;
187
188def: T_vcmp_pat<A2_vcmpbeq, seteq, v8i8>;
189def: T_vcmp_pat<A2_vcmpbgtu, setugt, v8i8>;
190def: T_vcmp_pat<A2_vcmpheq, seteq, v4i16>;
191def: T_vcmp_pat<A2_vcmphgt, setgt, v4i16>;
192def: T_vcmp_pat<A2_vcmphgtu, setugt, v4i16>;
193def: T_vcmp_pat<A2_vcmpweq, seteq, v2i32>;
194def: T_vcmp_pat<A2_vcmpwgt, setgt, v2i32>;
195def: T_vcmp_pat<A2_vcmpwgtu, setugt, v2i32>;
196
197// Add halfword.
198def: Pat<(sext_inreg (add I32:$src1, I32:$src2), i16),
199 (A2_addh_l16_ll I32:$src1, I32:$src2)>;
200
201def: Pat<(sra (add (shl I32:$src1, (i32 16)), I32:$src2), (i32 16)),
202 (A2_addh_l16_hl I32:$src1, I32:$src2)>;
203
204def: Pat<(shl (add I32:$src1, I32:$src2), (i32 16)),
205 (A2_addh_h16_ll I32:$src1, I32:$src2)>;
206
207// Subtract halfword.
208def: Pat<(sext_inreg (sub I32:$src1, I32:$src2), i16),
209 (A2_subh_l16_ll I32:$src1, I32:$src2)>;
210
211def: Pat<(shl (sub I32:$src1, I32:$src2), (i32 16)),
212 (A2_subh_h16_ll I32:$src1, I32:$src2)>;
213
214// Here, depending on the operand being selected, we'll either generate a
215// min or max instruction.
216// Ex:
217// (a>b)?a:b --> max(a,b) => Here check performed is '>' and the value selected
218// is the larger of two. So, the corresponding HexagonInst is passed in 'Inst'.
219// (a>b)?b:a --> min(a,b) => Here check performed is '>' but the smaller value
220// is selected and the corresponding HexagonInst is passed in 'SwapInst'.
221
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000222multiclass T_MinMax_pats <PatFrag Op, PatLeaf Val,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000223 InstHexagon Inst, InstHexagon SwapInst> {
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000224 def: Pat<(select (i1 (Op Val:$src1, Val:$src2)), Val:$src1, Val:$src2),
225 (Inst Val:$src1, Val:$src2)>;
226 def: Pat<(select (i1 (Op Val:$src1, Val:$src2)), Val:$src2, Val:$src1),
227 (SwapInst Val:$src1, Val:$src2)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000228}
229
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000230def IsPosHalf : PatLeaf<(i32 IntRegs:$a), [{
Krzysztof Parzyszek2839b292016-11-05 21:44:50 +0000231 return isPositiveHalfWord(N);
232}]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000233
234multiclass MinMax_pats <PatFrag Op, InstHexagon Inst, InstHexagon SwapInst> {
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000235 defm: T_MinMax_pats<Op, I32, Inst, SwapInst>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000236
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000237 def: Pat<(sext_inreg (select (i1 (Op IsPosHalf:$src1, IsPosHalf:$src2)),
238 IsPosHalf:$src1, IsPosHalf:$src2),
239 i16),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000240 (Inst IntRegs:$src1, IntRegs:$src2)>;
241
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000242 def: Pat<(sext_inreg (select (i1 (Op IsPosHalf:$src1, IsPosHalf:$src2)),
243 IsPosHalf:$src2, IsPosHalf:$src1),
244 i16),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000245 (SwapInst IntRegs:$src1, IntRegs:$src2)>;
246}
247
248let AddedComplexity = 200 in {
249 defm: MinMax_pats<setge, A2_max, A2_min>;
250 defm: MinMax_pats<setgt, A2_max, A2_min>;
251 defm: MinMax_pats<setle, A2_min, A2_max>;
252 defm: MinMax_pats<setlt, A2_min, A2_max>;
253 defm: MinMax_pats<setuge, A2_maxu, A2_minu>;
254 defm: MinMax_pats<setugt, A2_maxu, A2_minu>;
255 defm: MinMax_pats<setule, A2_minu, A2_maxu>;
256 defm: MinMax_pats<setult, A2_minu, A2_maxu>;
257}
258
259class T_cmp64_rr_pat<InstHexagon MI, PatFrag CmpOp>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000260 : Pat<(i1 (CmpOp I64:$Rs, I64:$Rt)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000261 (i1 (MI DoubleRegs:$Rs, DoubleRegs:$Rt))>;
262
263def: T_cmp64_rr_pat<C2_cmpeqp, seteq>;
264def: T_cmp64_rr_pat<C2_cmpgtp, setgt>;
265def: T_cmp64_rr_pat<C2_cmpgtup, setugt>;
266def: T_cmp64_rr_pat<C2_cmpgtp, RevCmp<setlt>>;
267def: T_cmp64_rr_pat<C2_cmpgtup, RevCmp<setult>>;
268
269def: Pat<(i64 (add I64:$Rs, I64:$Rt)), (A2_addp I64:$Rs, I64:$Rt)>;
270def: Pat<(i64 (sub I64:$Rs, I64:$Rt)), (A2_subp I64:$Rs, I64:$Rt)>;
271
272def: Pat<(i64 (and I64:$Rs, I64:$Rt)), (A2_andp I64:$Rs, I64:$Rt)>;
273def: Pat<(i64 (or I64:$Rs, I64:$Rt)), (A2_orp I64:$Rs, I64:$Rt)>;
274def: Pat<(i64 (xor I64:$Rs, I64:$Rt)), (A2_xorp I64:$Rs, I64:$Rt)>;
275
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000276def: Pat<(i1 (not I1:$Ps)), (C2_not PredRegs:$Ps)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000277
278def: Pat<(i1 (and I1:$Ps, I1:$Pt)), (C2_and I1:$Ps, I1:$Pt)>;
279def: Pat<(i1 (or I1:$Ps, I1:$Pt)), (C2_or I1:$Ps, I1:$Pt)>;
280def: Pat<(i1 (xor I1:$Ps, I1:$Pt)), (C2_xor I1:$Ps, I1:$Pt)>;
281def: Pat<(i1 (and I1:$Ps, (not I1:$Pt))), (C2_andn I1:$Ps, I1:$Pt)>;
282def: Pat<(i1 (or I1:$Ps, (not I1:$Pt))), (C2_orn I1:$Ps, I1:$Pt)>;
283
284def retflag : SDNode<"HexagonISD::RET_FLAG", SDTNone,
285 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
286def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone, [SDNPHasChain]>;
287
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000288def: Pat<(br bb:$dst), (J2_jump b30_2Imm:$dst)>;
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000289def: Pat<(brcond I1:$src1, bb:$block), (J2_jumpt PredRegs:$src1, bb:$block)>;
290def: Pat<(brind I32:$dst), (J2_jumpr IntRegs:$dst)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000291
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000292def: Pat<(retflag), (PS_jmpret (i32 R31))>;
293def: Pat<(eh_return), (EH_RETURN_JMPR (i32 R31))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000294
295// Patterns to select load-indexed (i.e. load from base+offset).
296multiclass Loadx_pat<PatFrag Load, ValueType VT, PatLeaf ImmPred,
297 InstHexagon MI> {
298 def: Pat<(VT (Load AddrFI:$fi)), (VT (MI AddrFI:$fi, 0))>;
299 def: Pat<(VT (Load (add (i32 AddrFI:$fi), ImmPred:$Off))),
300 (VT (MI AddrFI:$fi, imm:$Off))>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +0000301 def: Pat<(VT (Load (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000302 (VT (MI AddrFI:$fi, imm:$Off))>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000303 def: Pat<(VT (Load (add I32:$Rs, ImmPred:$Off))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000304 (VT (MI IntRegs:$Rs, imm:$Off))>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000305 def: Pat<(VT (Load I32:$Rs)), (VT (MI IntRegs:$Rs, 0))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000306}
307
308let AddedComplexity = 20 in {
309 defm: Loadx_pat<load, i32, s30_2ImmPred, L2_loadri_io>;
310 defm: Loadx_pat<load, i64, s29_3ImmPred, L2_loadrd_io>;
311 defm: Loadx_pat<atomic_load_8 , i32, s32_0ImmPred, L2_loadrub_io>;
312 defm: Loadx_pat<atomic_load_16, i32, s31_1ImmPred, L2_loadruh_io>;
313 defm: Loadx_pat<atomic_load_32, i32, s30_2ImmPred, L2_loadri_io>;
314 defm: Loadx_pat<atomic_load_64, i64, s29_3ImmPred, L2_loadrd_io>;
315
316 defm: Loadx_pat<extloadi1, i32, s32_0ImmPred, L2_loadrub_io>;
317 defm: Loadx_pat<extloadi8, i32, s32_0ImmPred, L2_loadrub_io>;
318 defm: Loadx_pat<extloadi16, i32, s31_1ImmPred, L2_loadruh_io>;
319 defm: Loadx_pat<sextloadi8, i32, s32_0ImmPred, L2_loadrb_io>;
320 defm: Loadx_pat<sextloadi16, i32, s31_1ImmPred, L2_loadrh_io>;
321 defm: Loadx_pat<zextloadi1, i32, s32_0ImmPred, L2_loadrub_io>;
322 defm: Loadx_pat<zextloadi8, i32, s32_0ImmPred, L2_loadrub_io>;
323 defm: Loadx_pat<zextloadi16, i32, s31_1ImmPred, L2_loadruh_io>;
324 // No sextloadi1.
325}
326
327// Sign-extending loads of i1 need to replicate the lowest bit throughout
328// the 32-bit value. Since the loaded value can only be 0 or 1, 0-v should
329// do the trick.
330let AddedComplexity = 20 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000331def: Pat<(i32 (sextloadi1 I32:$Rs)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000332 (A2_subri 0, (L2_loadrub_io IntRegs:$Rs, 0))>;
333
334def: Pat<(i32 (mul I32:$src1, I32:$src2)), (M2_mpyi I32:$src1, I32:$src2)>;
335def: Pat<(i32 (mulhs I32:$src1, I32:$src2)), (M2_mpy_up I32:$src1, I32:$src2)>;
336def: Pat<(i32 (mulhu I32:$src1, I32:$src2)), (M2_mpyu_up I32:$src1, I32:$src2)>;
337
338def: Pat<(mul IntRegs:$Rs, u32_0ImmPred:$u8),
339 (M2_mpysip IntRegs:$Rs, imm:$u8)>;
340def: Pat<(ineg (mul IntRegs:$Rs, u8_0ImmPred:$u8)),
341 (M2_mpysin IntRegs:$Rs, imm:$u8)>;
342def: Pat<(mul IntRegs:$src1, s32_0ImmPred:$src2),
343 (M2_mpysmi IntRegs:$src1, imm:$src2)>;
344def: Pat<(add (mul IntRegs:$src2, u32_0ImmPred:$src3), IntRegs:$src1),
345 (M2_macsip IntRegs:$src1, IntRegs:$src2, imm:$src3)>;
346def: Pat<(add (mul I32:$src2, I32:$src3), I32:$src1),
347 (M2_maci IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
348def: Pat<(add (add IntRegs:$src2, u32_0ImmPred:$src3), IntRegs:$src1),
349 (M2_accii IntRegs:$src1, IntRegs:$src2, imm:$src3)>;
350def: Pat<(add (add I32:$src2, I32:$src3), I32:$src1),
351 (M2_acci IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
352
353class T_MType_acc_pat1 <InstHexagon MI, SDNode firstOp, SDNode secOp,
354 PatLeaf ImmPred>
355 : Pat <(secOp IntRegs:$src1, (firstOp IntRegs:$src2, ImmPred:$src3)),
356 (MI IntRegs:$src1, IntRegs:$src2, ImmPred:$src3)>;
357
358class T_MType_acc_pat2 <InstHexagon MI, SDNode firstOp, SDNode secOp>
359 : Pat <(i32 (secOp IntRegs:$src1, (firstOp IntRegs:$src2, IntRegs:$src3))),
360 (MI IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
361
362def : T_MType_acc_pat2 <M2_xor_xacc, xor, xor>;
363def : T_MType_acc_pat1 <M2_macsin, mul, sub, u32_0ImmPred>;
364
365def : T_MType_acc_pat1 <M2_naccii, add, sub, s32_0ImmPred>;
366def : T_MType_acc_pat2 <M2_nacci, add, sub>;
367
368def: T_MType_acc_pat2 <M4_or_xor, xor, or>;
369def: T_MType_acc_pat2 <M4_and_xor, xor, and>;
370def: T_MType_acc_pat2 <M4_or_and, and, or>;
371def: T_MType_acc_pat2 <M4_and_and, and, and>;
372def: T_MType_acc_pat2 <M4_xor_and, and, xor>;
373def: T_MType_acc_pat2 <M4_or_or, or, or>;
374def: T_MType_acc_pat2 <M4_and_or, or, and>;
375def: T_MType_acc_pat2 <M4_xor_or, or, xor>;
376
377class T_MType_acc_pat3 <InstHexagon MI, SDNode firstOp, SDNode secOp>
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000378 : Pat <(secOp I32:$src1, (firstOp I32:$src2, (not I32:$src3))),
379 (MI IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000380
381def: T_MType_acc_pat3 <M4_or_andn, and, or>;
382def: T_MType_acc_pat3 <M4_and_andn, and, and>;
383def: T_MType_acc_pat3 <M4_xor_andn, and, xor>;
384
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000385// This complex pattern is really only to detect various forms of
386// sign-extension i32->i64. The selected value will be of type i64
387// whose low word is the value being extended. The high word is
388// unspecified.
389def Usxtw : ComplexPattern<i64, 1, "DetectUseSxtw", [], []>;
390
Krzysztof Parzyszek84755102016-11-06 17:56:48 +0000391def Aext64: PatFrag<(ops node:$Rs), (i64 (anyext node:$Rs))>;
Krzysztof Parzyszek84755102016-11-06 17:56:48 +0000392def Zext64: PatFrag<(ops node:$Rs), (i64 (zext node:$Rs))>;
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000393def Sext64: PatLeaf<(i64 Usxtw:$Rs)>;
Krzysztof Parzyszek84755102016-11-06 17:56:48 +0000394
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000395def: Pat<(mul (Aext64 I32:$Rs), (Aext64 I32:$Rt)),
396 (M2_dpmpyuu_s0 I32:$Rs, I32:$Rt)>;
Krzysztof Parzyszek2839b292016-11-05 21:44:50 +0000397
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000398def: Pat<(mul Sext64:$Rs, Sext64:$Rt),
399 (M2_dpmpyss_s0 (LoReg Sext64:$Rs), (LoReg Sext64:$Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000400
401// Multiply and accumulate, use full result.
402// Rxx[+-]=mpy(Rs,Rt)
403
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000404def: Pat<(add I64:$Rx, (mul Sext64:$Rs, Sext64:$Rt)),
405 (M2_dpmpyss_acc_s0 I64:$Rx, (LoReg Sext64:$Rs), (LoReg Sext64:$Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000406
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000407def: Pat<(sub I64:$Rx, (mul Sext64:$Rs, Sext64:$Rt)),
408 (M2_dpmpyss_nac_s0 I64:$Rx, (LoReg Sext64:$Rs), (LoReg Sext64:$Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000409
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000410def: Pat<(add I64:$Rx, (mul (Aext64 I32:$Rs), (Aext64 I32:$Rt))),
411 (M2_dpmpyuu_acc_s0 I64:$Rx, I32:$Rs, I32:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000412
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000413def: Pat<(add I64:$Rx, (mul (Zext64 I32:$Rs), (Zext64 I32:$Rt))),
414 (M2_dpmpyuu_acc_s0 I64:$Rx, I32:$Rs, I32:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000415
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000416def: Pat<(sub I64:$Rx, (mul (Aext64 I32:$Rs), (Aext64 I32:$Rt))),
417 (M2_dpmpyuu_nac_s0 I64:$Rx, I32:$Rs, I32:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000418
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000419def: Pat<(sub I64:$Rx, (mul (Zext64 I32:$Rs), (Zext64 I32:$Rt))),
420 (M2_dpmpyuu_nac_s0 I64:$Rx, I32:$Rs, I32:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000421
422class Storepi_pat<PatFrag Store, PatFrag Value, PatFrag Offset,
423 InstHexagon MI>
424 : Pat<(Store Value:$src1, I32:$src2, Offset:$offset),
425 (MI I32:$src2, imm:$offset, Value:$src1)>;
426
427def: Storepi_pat<post_truncsti8, I32, s4_0ImmPred, S2_storerb_pi>;
428def: Storepi_pat<post_truncsti16, I32, s4_1ImmPred, S2_storerh_pi>;
429def: Storepi_pat<post_store, I32, s4_2ImmPred, S2_storeri_pi>;
430def: Storepi_pat<post_store, I64, s4_3ImmPred, S2_storerd_pi>;
431
432// Patterns for generating stores, where the address takes different forms:
433// - frameindex,
434// - frameindex + offset,
435// - base + offset,
436// - simple (base address without offset).
437// These would usually be used together (via Storex_pat defined below), but
438// in some cases one may want to apply different properties (such as
439// AddedComplexity) to the individual patterns.
440class Storex_fi_pat<PatFrag Store, PatFrag Value, InstHexagon MI>
441 : Pat<(Store Value:$Rs, AddrFI:$fi), (MI AddrFI:$fi, 0, Value:$Rs)>;
442multiclass Storex_fi_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred,
443 InstHexagon MI> {
444 def: Pat<(Store Value:$Rs, (add (i32 AddrFI:$fi), ImmPred:$Off)),
445 (MI AddrFI:$fi, imm:$Off, Value:$Rs)>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +0000446 def: Pat<(Store Value:$Rs, (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000447 (MI AddrFI:$fi, imm:$Off, Value:$Rs)>;
448}
449multiclass Storex_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred,
450 InstHexagon MI> {
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000451 def: Pat<(Store Value:$Rt, (add I32:$Rs, ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000452 (MI IntRegs:$Rs, imm:$Off, Value:$Rt)>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +0000453 def: Pat<(Store Value:$Rt, (IsOrAdd I32:$Rs, ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000454 (MI IntRegs:$Rs, imm:$Off, Value:$Rt)>;
455}
456class Storex_simple_pat<PatFrag Store, PatFrag Value, InstHexagon MI>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000457 : Pat<(Store Value:$Rt, I32:$Rs),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000458 (MI IntRegs:$Rs, 0, Value:$Rt)>;
459
460// Patterns for generating stores, where the address takes different forms,
461// and where the value being stored is transformed through the value modifier
462// ValueMod. The address forms are same as above.
463class Storexm_fi_pat<PatFrag Store, PatFrag Value, PatFrag ValueMod,
464 InstHexagon MI>
465 : Pat<(Store Value:$Rs, AddrFI:$fi),
466 (MI AddrFI:$fi, 0, (ValueMod Value:$Rs))>;
467multiclass Storexm_fi_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred,
468 PatFrag ValueMod, InstHexagon MI> {
469 def: Pat<(Store Value:$Rs, (add (i32 AddrFI:$fi), ImmPred:$Off)),
470 (MI AddrFI:$fi, imm:$Off, (ValueMod Value:$Rs))>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +0000471 def: Pat<(Store Value:$Rs, (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000472 (MI AddrFI:$fi, imm:$Off, (ValueMod Value:$Rs))>;
473}
474multiclass Storexm_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred,
475 PatFrag ValueMod, InstHexagon MI> {
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000476 def: Pat<(Store Value:$Rt, (add I32:$Rs, ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000477 (MI IntRegs:$Rs, imm:$Off, (ValueMod Value:$Rt))>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +0000478 def: Pat<(Store Value:$Rt, (IsOrAdd I32:$Rs, ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000479 (MI IntRegs:$Rs, imm:$Off, (ValueMod Value:$Rt))>;
480}
481class Storexm_simple_pat<PatFrag Store, PatFrag Value, PatFrag ValueMod,
482 InstHexagon MI>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000483 : Pat<(Store Value:$Rt, I32:$Rs),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000484 (MI IntRegs:$Rs, 0, (ValueMod Value:$Rt))>;
485
486multiclass Storex_pat<PatFrag Store, PatFrag Value, PatLeaf ImmPred,
487 InstHexagon MI> {
488 def: Storex_fi_pat <Store, Value, MI>;
489 defm: Storex_fi_add_pat <Store, Value, ImmPred, MI>;
490 defm: Storex_add_pat <Store, Value, ImmPred, MI>;
491}
492
493multiclass Storexm_pat<PatFrag Store, PatFrag Value, PatLeaf ImmPred,
494 PatFrag ValueMod, InstHexagon MI> {
495 def: Storexm_fi_pat <Store, Value, ValueMod, MI>;
496 defm: Storexm_fi_add_pat <Store, Value, ImmPred, ValueMod, MI>;
497 defm: Storexm_add_pat <Store, Value, ImmPred, ValueMod, MI>;
498}
499
500// Regular stores in the DAG have two operands: value and address.
501// Atomic stores also have two, but they are reversed: address, value.
502// To use atomic stores with the patterns, they need to have their operands
503// swapped. This relies on the knowledge that the F.Fragment uses names
504// "ptr" and "val".
505class SwapSt<PatFrag F>
506 : PatFrag<(ops node:$val, node:$ptr), F.Fragment, F.PredicateCode,
507 F.OperandTransform>;
508
509let AddedComplexity = 20 in {
510 defm: Storex_pat<truncstorei8, I32, s32_0ImmPred, S2_storerb_io>;
511 defm: Storex_pat<truncstorei16, I32, s31_1ImmPred, S2_storerh_io>;
512 defm: Storex_pat<store, I32, s30_2ImmPred, S2_storeri_io>;
513 defm: Storex_pat<store, I64, s29_3ImmPred, S2_storerd_io>;
514
515 defm: Storex_pat<SwapSt<atomic_store_8>, I32, s32_0ImmPred, S2_storerb_io>;
516 defm: Storex_pat<SwapSt<atomic_store_16>, I32, s31_1ImmPred, S2_storerh_io>;
517 defm: Storex_pat<SwapSt<atomic_store_32>, I32, s30_2ImmPred, S2_storeri_io>;
518 defm: Storex_pat<SwapSt<atomic_store_64>, I64, s29_3ImmPred, S2_storerd_io>;
519}
520
521// Simple patterns should be tried with the least priority.
522def: Storex_simple_pat<truncstorei8, I32, S2_storerb_io>;
523def: Storex_simple_pat<truncstorei16, I32, S2_storerh_io>;
524def: Storex_simple_pat<store, I32, S2_storeri_io>;
525def: Storex_simple_pat<store, I64, S2_storerd_io>;
526
527def: Storex_simple_pat<SwapSt<atomic_store_8>, I32, S2_storerb_io>;
528def: Storex_simple_pat<SwapSt<atomic_store_16>, I32, S2_storerh_io>;
529def: Storex_simple_pat<SwapSt<atomic_store_32>, I32, S2_storeri_io>;
530def: Storex_simple_pat<SwapSt<atomic_store_64>, I64, S2_storerd_io>;
531
532let AddedComplexity = 20 in {
533 defm: Storexm_pat<truncstorei8, I64, s32_0ImmPred, LoReg, S2_storerb_io>;
534 defm: Storexm_pat<truncstorei16, I64, s31_1ImmPred, LoReg, S2_storerh_io>;
535 defm: Storexm_pat<truncstorei32, I64, s30_2ImmPred, LoReg, S2_storeri_io>;
536}
537
538def: Storexm_simple_pat<truncstorei8, I64, LoReg, S2_storerb_io>;
539def: Storexm_simple_pat<truncstorei16, I64, LoReg, S2_storerh_io>;
540def: Storexm_simple_pat<truncstorei32, I64, LoReg, S2_storeri_io>;
541
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000542def: Pat <(i64 (sext I32:$src)), (A2_sxtw I32:$src)>;
543def: Pat <(i64 (sext_inreg I64:$src, i32)), (A2_sxtw (LoReg I64:$src))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000544
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000545def: Pat<(select (i1 (setlt I32:$src, 0)), (sub 0, I32:$src), I32:$src),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000546 (A2_abs IntRegs:$src)>;
547
548let AddedComplexity = 50 in
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000549def: Pat<(xor (add (sra I32:$src, (i32 31)),
550 I32:$src),
551 (sra I32:$src, (i32 31))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000552 (A2_abs IntRegs:$src)>;
553
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000554def: Pat<(sra I32:$src, u5_0ImmPred:$u5),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000555 (S2_asr_i_r IntRegs:$src, imm:$u5)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000556def: Pat<(srl I32:$src, u5_0ImmPred:$u5),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000557 (S2_lsr_i_r IntRegs:$src, imm:$u5)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000558def: Pat<(shl I32:$src, u5_0ImmPred:$u5),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000559 (S2_asl_i_r IntRegs:$src, imm:$u5)>;
560
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000561def: Pat<(sra (add (sra I32:$src1, u5_0ImmPred:$src2), 1), (i32 1)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000562 (S2_asr_i_r_rnd IntRegs:$src1, u5_0ImmPred:$src2)>;
563
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000564def : Pat<(not I64:$src1),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000565 (A2_notp DoubleRegs:$src1)>;
566
567// Count leading zeros.
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000568def: Pat<(ctlz I32:$Rs), (S2_cl0 I32:$Rs)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000569def: Pat<(i32 (trunc (ctlz I64:$Rss))), (S2_cl0p I64:$Rss)>;
570
571// Count trailing zeros: 32-bit.
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000572def: Pat<(cttz I32:$Rs), (S2_ct0 I32:$Rs)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000573
574// Count leading ones.
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000575def: Pat<(ctlz (not I32:$Rs)), (S2_cl1 I32:$Rs)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000576def: Pat<(i32 (trunc (ctlz (not I64:$Rss)))), (S2_cl1p I64:$Rss)>;
577
578// Count trailing ones: 32-bit.
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000579def: Pat<(cttz (not I32:$Rs)), (S2_ct1 I32:$Rs)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000580
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +0000581let AddedComplexity = 20 in { // Complexity greater than and/or/xor
582 def: Pat<(and I32:$Rs, IsNPow2_32:$V),
583 (S2_clrbit_i IntRegs:$Rs, (LogN2_32 $V))>;
584 def: Pat<(or I32:$Rs, IsPow2_32:$V),
585 (S2_setbit_i IntRegs:$Rs, (Log2_32 $V))>;
586 def: Pat<(xor I32:$Rs, IsPow2_32:$V),
587 (S2_togglebit_i IntRegs:$Rs, (Log2_32 $V))>;
588
589 def: Pat<(and I32:$Rs, (not (shl 1, I32:$Rt))),
590 (S2_clrbit_r IntRegs:$Rs, IntRegs:$Rt)>;
591 def: Pat<(or I32:$Rs, (shl 1, I32:$Rt)),
592 (S2_setbit_r IntRegs:$Rs, IntRegs:$Rt)>;
593 def: Pat<(xor I32:$Rs, (shl 1, I32:$Rt)),
594 (S2_togglebit_r IntRegs:$Rs, IntRegs:$Rt)>;
595}
596
597// Clr/set/toggle bit for 64-bit values with immediate bit index.
598let AddedComplexity = 20 in { // Complexity greater than and/or/xor
599 def: Pat<(and I64:$Rss, IsNPow2_64L:$V),
600 (REG_SEQUENCE DoubleRegs,
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +0000601 (i32 (HiReg $Rss)), isub_hi,
602 (S2_clrbit_i (LoReg $Rss), (LogN2_64 $V)), isub_lo)>;
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +0000603 def: Pat<(and I64:$Rss, IsNPow2_64H:$V),
604 (REG_SEQUENCE DoubleRegs,
605 (S2_clrbit_i (HiReg $Rss), (UDEC32 (i32 (LogN2_64 $V)))),
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +0000606 isub_hi,
607 (i32 (LoReg $Rss)), isub_lo)>;
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +0000608
609 def: Pat<(or I64:$Rss, IsPow2_64L:$V),
610 (REG_SEQUENCE DoubleRegs,
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +0000611 (i32 (HiReg $Rss)), isub_hi,
612 (S2_setbit_i (LoReg $Rss), (Log2_64 $V)), isub_lo)>;
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +0000613 def: Pat<(or I64:$Rss, IsPow2_64H:$V),
614 (REG_SEQUENCE DoubleRegs,
615 (S2_setbit_i (HiReg $Rss), (UDEC32 (i32 (Log2_64 $V)))),
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +0000616 isub_hi,
617 (i32 (LoReg $Rss)), isub_lo)>;
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +0000618
619 def: Pat<(xor I64:$Rss, IsPow2_64L:$V),
620 (REG_SEQUENCE DoubleRegs,
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +0000621 (i32 (HiReg $Rss)), isub_hi,
622 (S2_togglebit_i (LoReg $Rss), (Log2_64 $V)), isub_lo)>;
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +0000623 def: Pat<(xor I64:$Rss, IsPow2_64H:$V),
624 (REG_SEQUENCE DoubleRegs,
625 (S2_togglebit_i (HiReg $Rss), (UDEC32 (i32 (Log2_64 $V)))),
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +0000626 isub_hi,
627 (i32 (LoReg $Rss)), isub_lo)>;
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +0000628}
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000629
630let AddedComplexity = 20 in { // Complexity greater than cmp reg-imm.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000631 def: Pat<(i1 (setne (and (shl 1, u5_0ImmPred:$u5), I32:$Rs), 0)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000632 (S2_tstbit_i IntRegs:$Rs, u5_0ImmPred:$u5)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000633 def: Pat<(i1 (setne (and (shl 1, I32:$Rt), I32:$Rs), 0)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000634 (S2_tstbit_r IntRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000635 def: Pat<(i1 (trunc I32:$Rs)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000636 (S2_tstbit_i IntRegs:$Rs, 0)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000637 def: Pat<(i1 (trunc I64:$Rs)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000638 (S2_tstbit_i (LoReg DoubleRegs:$Rs), 0)>;
639}
640
641let AddedComplexity = 20 in { // Complexity greater than compare reg-imm.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000642 def: Pat<(i1 (seteq (and I32:$Rs, u6_0ImmPred:$u6), 0)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000643 (C2_bitsclri IntRegs:$Rs, u6_0ImmPred:$u6)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000644 def: Pat<(i1 (seteq (and I32:$Rs, I32:$Rt), 0)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000645 (C2_bitsclr IntRegs:$Rs, IntRegs:$Rt)>;
646}
647
648let AddedComplexity = 10 in // Complexity greater than compare reg-reg.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000649def: Pat<(i1 (seteq (and I32:$Rs, I32:$Rt), IntRegs:$Rt)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000650 (C2_bitsset IntRegs:$Rs, IntRegs:$Rt)>;
651
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000652def: Pat<(or (or (shl (or (shl (i32 (extloadi8 (add I32:$b, 3))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000653 (i32 8)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000654 (i32 (zextloadi8 (add I32:$b, 2)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000655 (i32 16)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000656 (shl (i32 (zextloadi8 (add I32:$b, 1))), (i32 8))),
657 (zextloadi8 I32:$b)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000658 (A2_swiz (L2_loadri_io IntRegs:$b, 0))>;
659
660// Patterns for loads of i1:
661def: Pat<(i1 (load AddrFI:$fi)),
662 (C2_tfrrp (L2_loadrub_io AddrFI:$fi, 0))>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000663def: Pat<(i1 (load (add I32:$Rs, s32_0ImmPred:$Off))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000664 (C2_tfrrp (L2_loadrub_io IntRegs:$Rs, imm:$Off))>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000665def: Pat<(i1 (load I32:$Rs)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000666 (C2_tfrrp (L2_loadrub_io IntRegs:$Rs, 0))>;
667
668def I1toI32: OutPatFrag<(ops node:$Rs),
669 (C2_muxii (i1 $Rs), 1, 0)>;
670
671def I32toI1: OutPatFrag<(ops node:$Rs),
672 (i1 (C2_tfrrp (i32 $Rs)))>;
673
674defm: Storexm_pat<store, I1, s32_0ImmPred, I1toI32, S2_storerb_io>;
675def: Storexm_simple_pat<store, I1, I1toI32, S2_storerb_io>;
676
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000677def: Pat<(sra I64:$src, u6_0ImmPred:$u6),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000678 (S2_asr_i_p DoubleRegs:$src, imm:$u6)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000679def: Pat<(srl I64:$src, u6_0ImmPred:$u6),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000680 (S2_lsr_i_p DoubleRegs:$src, imm:$u6)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000681def: Pat<(shl I64:$src, u6_0ImmPred:$u6),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000682 (S2_asl_i_p DoubleRegs:$src, imm:$u6)>;
683
684let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000685def: Pat<(add I32:$Rt, (shl I32:$Rs, u3_0ImmPred:$u3)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000686 (S2_addasl_rrri IntRegs:$Rt, IntRegs:$Rs, imm:$u3)>;
687
688def HexagonBARRIER: SDNode<"HexagonISD::BARRIER", SDTNone, [SDNPHasChain]>;
689def: Pat<(HexagonBARRIER), (Y2_barrier)>;
690
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +0000691def: Pat<(IsOrAdd (i32 AddrFI:$Rs), s32_0ImmPred:$off),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000692 (PS_fi (i32 AddrFI:$Rs), s32_0ImmPred:$off)>;
693
694
695// Support for generating global address.
696// Taken from X86InstrInfo.td.
697def SDTHexagonCONST32 : SDTypeProfile<1, 1, [SDTCisVT<0, i32>,
698 SDTCisVT<1, i32>,
699 SDTCisPtrTy<0>]>;
700def HexagonCONST32 : SDNode<"HexagonISD::CONST32", SDTHexagonCONST32>;
701def HexagonCONST32_GP : SDNode<"HexagonISD::CONST32_GP", SDTHexagonCONST32>;
702
703// Map TLS addressses to A2_tfrsi.
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000704def: Pat<(HexagonCONST32 tglobaltlsaddr:$addr), (A2_tfrsi s32_0Imm:$addr)>;
705def: Pat<(HexagonCONST32 bbl:$label), (A2_tfrsi s32_0Imm:$label)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000706
707def: Pat<(i64 imm:$v), (CONST64 imm:$v)>;
708def: Pat<(i1 0), (PS_false)>;
709def: Pat<(i1 1), (PS_true)>;
710
711// Pseudo instructions.
Serge Pavlovd526b132017-05-09 13:35:13 +0000712def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32>,
713 SDTCisVT<1, i32> ]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000714def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>,
715 SDTCisVT<1, i32> ]>;
716
717def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart,
718 [SDNPHasChain, SDNPOutGlue]>;
719def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd,
720 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
721
722def SDT_SPCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
723
724// For tailcalls a HexagonTCRet SDNode has 3 SDNode Properties - a chain,
725// Optional Flag and Variable Arguments.
726// Its 1 Operand has pointer type.
727def HexagonTCRet : SDNode<"HexagonISD::TC_RETURN", SDT_SPCall,
728 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
729
730
Serge Pavlovd526b132017-05-09 13:35:13 +0000731def: Pat<(callseq_start timm:$amt, timm:$amt2),
732 (ADJCALLSTACKDOWN imm:$amt, imm:$amt2)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000733def: Pat<(callseq_end timm:$amt1, timm:$amt2),
734 (ADJCALLSTACKUP imm:$amt1, imm:$amt2)>;
735
736//Tail calls.
737def: Pat<(HexagonTCRet tglobaladdr:$dst),
738 (PS_tailcall_i tglobaladdr:$dst)>;
739def: Pat<(HexagonTCRet texternalsym:$dst),
740 (PS_tailcall_i texternalsym:$dst)>;
741def: Pat<(HexagonTCRet I32:$dst),
742 (PS_tailcall_r I32:$dst)>;
743
744// Map from r0 = and(r1, 65535) to r0 = zxth(r1)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000745def: Pat<(and I32:$src1, 65535),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000746 (A2_zxth IntRegs:$src1)>;
747
748// Map from r0 = and(r1, 255) to r0 = zxtb(r1).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000749def: Pat<(and I32:$src1, 255),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000750 (A2_zxtb IntRegs:$src1)>;
751
752// Map Add(p1, true) to p1 = not(p1).
753// Add(p1, false) should never be produced,
754// if it does, it got to be mapped to NOOP.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000755def: Pat<(add I1:$src1, -1),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000756 (C2_not PredRegs:$src1)>;
757
758// Map from p0 = pnot(p0); r0 = mux(p0, #i, #j) => r0 = mux(p0, #j, #i).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000759def: Pat<(select (not I1:$src1), s8_0ImmPred:$src2, s32_0ImmPred:$src3),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000760 (C2_muxii PredRegs:$src1, s32_0ImmPred:$src3, s8_0ImmPred:$src2)>;
761
762// Map from p0 = pnot(p0); r0 = select(p0, #i, r1)
763// => r0 = C2_muxir(p0, r1, #i)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000764def: Pat<(select (not I1:$src1), s32_0ImmPred:$src2,
765 I32:$src3),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000766 (C2_muxir PredRegs:$src1, IntRegs:$src3, s32_0ImmPred:$src2)>;
767
768// Map from p0 = pnot(p0); r0 = mux(p0, r1, #i)
769// => r0 = C2_muxri (p0, #i, r1)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000770def: Pat<(select (not I1:$src1), IntRegs:$src2, s32_0ImmPred:$src3),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000771 (C2_muxri PredRegs:$src1, s32_0ImmPred:$src3, IntRegs:$src2)>;
772
773// Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000774def: Pat<(brcond (not I1:$src1), bb:$offset),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000775 (J2_jumpf PredRegs:$src1, bb:$offset)>;
776
777// Map from Rdd = sign_extend_inreg(Rss, i32) -> Rdd = A2_sxtw(Rss.lo).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000778def: Pat<(i64 (sext_inreg I64:$src1, i32)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000779 (A2_sxtw (LoReg DoubleRegs:$src1))>;
780
781// Map from Rdd = sign_extend_inreg(Rss, i16) -> Rdd = A2_sxtw(A2_sxth(Rss.lo)).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000782def: Pat<(i64 (sext_inreg I64:$src1, i16)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000783 (A2_sxtw (A2_sxth (LoReg DoubleRegs:$src1)))>;
784
785// Map from Rdd = sign_extend_inreg(Rss, i8) -> Rdd = A2_sxtw(A2_sxtb(Rss.lo)).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000786def: Pat<(i64 (sext_inreg I64:$src1, i8)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000787 (A2_sxtw (A2_sxtb (LoReg DoubleRegs:$src1)))>;
788
789// We want to prevent emitting pnot's as much as possible.
790// Map brcond with an unsupported setcc to a J2_jumpf.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000791def : Pat <(brcond (i1 (setne I32:$src1, I32:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000792 bb:$offset),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000793 (J2_jumpf (C2_cmpeq I32:$src1, I32:$src2),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000794 bb:$offset)>;
795
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000796def : Pat <(brcond (i1 (setne I32:$src1, s10_0ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000797 bb:$offset),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000798 (J2_jumpf (C2_cmpeqi I32:$src1, s10_0ImmPred:$src2), bb:$offset)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000799
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000800def: Pat<(brcond (i1 (setne I1:$src1, (i1 -1))), bb:$offset),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000801 (J2_jumpf PredRegs:$src1, bb:$offset)>;
802
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000803def: Pat<(brcond (i1 (setne I1:$src1, (i1 0))), bb:$offset),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000804 (J2_jumpt PredRegs:$src1, bb:$offset)>;
805
806// cmp.lt(Rs, Imm) -> !cmp.ge(Rs, Imm) -> !cmp.gt(Rs, Imm-1)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000807def: Pat<(brcond (i1 (setlt I32:$src1, s8_0ImmPred:$src2)), bb:$offset),
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +0000808 (J2_jumpf (C2_cmpgti IntRegs:$src1, (SDEC1 s8_0ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000809 bb:$offset)>;
810
811// Map from a 64-bit select to an emulated 64-bit mux.
812// Hexagon does not support 64-bit MUXes; so emulate with combines.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000813def: Pat<(select I1:$src1, I64:$src2,
814 I64:$src3),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000815 (A2_combinew (C2_mux PredRegs:$src1, (HiReg DoubleRegs:$src2),
816 (HiReg DoubleRegs:$src3)),
817 (C2_mux PredRegs:$src1, (LoReg DoubleRegs:$src2),
818 (LoReg DoubleRegs:$src3)))>;
819
820// Map from a 1-bit select to logical ops.
821// From LegalizeDAG.cpp: (B1 ? B2 : B3) <=> (B1 & B2)|(!B1&B3).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000822def: Pat<(select I1:$src1, I1:$src2, I1:$src3),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000823 (C2_or (C2_and PredRegs:$src1, PredRegs:$src2),
824 (C2_and (C2_not PredRegs:$src1), PredRegs:$src3))>;
825
826// Map for truncating from 64 immediates to 32 bit immediates.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000827def: Pat<(i32 (trunc I64:$src)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000828 (LoReg DoubleRegs:$src)>;
829
830// Map for truncating from i64 immediates to i1 bit immediates.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000831def: Pat<(i1 (trunc I64:$src)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000832 (C2_tfrrp (LoReg DoubleRegs:$src))>;
833
834// rs <= rt -> !(rs > rt).
835let AddedComplexity = 30 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000836def: Pat<(i1 (setle I32:$src1, s32_0ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000837 (C2_not (C2_cmpgti IntRegs:$src1, s32_0ImmPred:$src2))>;
838
839// rs <= rt -> !(rs > rt).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000840def : Pat<(i1 (setle I32:$src1, I32:$src2)),
841 (i1 (C2_not (C2_cmpgt I32:$src1, I32:$src2)))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000842
843// Rss <= Rtt -> !(Rss > Rtt).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000844def: Pat<(i1 (setle I64:$src1, I64:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000845 (C2_not (C2_cmpgtp DoubleRegs:$src1, DoubleRegs:$src2))>;
846
847// Map cmpne -> cmpeq.
848// Hexagon_TODO: We should improve on this.
849// rs != rt -> !(rs == rt).
850let AddedComplexity = 30 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000851def: Pat<(i1 (setne I32:$src1, s32_0ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000852 (C2_not (C2_cmpeqi IntRegs:$src1, s32_0ImmPred:$src2))>;
853
854// Convert setne back to xor for hexagon since we compute w/ pred registers.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000855def: Pat<(i1 (setne I1:$src1, I1:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000856 (C2_xor PredRegs:$src1, PredRegs:$src2)>;
857
858// Map cmpne(Rss) -> !cmpew(Rss).
859// rs != rt -> !(rs == rt).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000860def: Pat<(i1 (setne I64:$src1, I64:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000861 (C2_not (C2_cmpeqp DoubleRegs:$src1, DoubleRegs:$src2))>;
862
863// Map cmpge(Rs, Rt) -> !cmpgt(Rs, Rt).
864// rs >= rt -> !(rt > rs).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000865def : Pat <(i1 (setge I32:$src1, I32:$src2)),
866 (i1 (C2_not (i1 (C2_cmpgt I32:$src2, I32:$src1))))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000867
868// cmpge(Rs, Imm) -> cmpgt(Rs, Imm-1)
869let AddedComplexity = 30 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000870def: Pat<(i1 (setge I32:$src1, s32_0ImmPred:$src2)),
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +0000871 (C2_cmpgti IntRegs:$src1, (SDEC1 s32_0ImmPred:$src2))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000872
873// Map cmpge(Rss, Rtt) -> !cmpgt(Rtt, Rss).
874// rss >= rtt -> !(rtt > rss).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000875def: Pat<(i1 (setge I64:$src1, I64:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000876 (C2_not (C2_cmpgtp DoubleRegs:$src2, DoubleRegs:$src1))>;
877
878// Map cmplt(Rs, Imm) -> !cmpge(Rs, Imm).
879// !cmpge(Rs, Imm) -> !cmpgt(Rs, Imm-1).
880// rs < rt -> !(rs >= rt).
881let AddedComplexity = 30 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000882def: Pat<(i1 (setlt I32:$src1, s32_0ImmPred:$src2)),
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +0000883 (C2_not (C2_cmpgti IntRegs:$src1, (SDEC1 s32_0ImmPred:$src2)))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000884
885// Generate cmpgeu(Rs, #0) -> cmpeq(Rs, Rs)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000886def: Pat<(i1 (setuge I32:$src1, 0)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000887 (C2_cmpeq IntRegs:$src1, IntRegs:$src1)>;
888
889// Generate cmpgeu(Rs, #u8) -> cmpgtu(Rs, #u8 -1)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000890def: Pat<(i1 (setuge I32:$src1, u32_0ImmPred:$src2)),
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +0000891 (C2_cmpgtui IntRegs:$src1, (UDEC1 u32_0ImmPred:$src2))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000892
893// Generate cmpgtu(Rs, #u9)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000894def: Pat<(i1 (setugt I32:$src1, u32_0ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000895 (C2_cmpgtui IntRegs:$src1, u32_0ImmPred:$src2)>;
896
897// Map from Rs >= Rt -> !(Rt > Rs).
898// rs >= rt -> !(rt > rs).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000899def: Pat<(i1 (setuge I64:$src1, I64:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000900 (C2_not (C2_cmpgtup DoubleRegs:$src2, DoubleRegs:$src1))>;
901
902// Map from cmpleu(Rss, Rtt) -> !cmpgtu(Rss, Rtt-1).
903// Map from (Rs <= Rt) -> !(Rs > Rt).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000904def: Pat<(i1 (setule I64:$src1, I64:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000905 (C2_not (C2_cmpgtup DoubleRegs:$src1, DoubleRegs:$src2))>;
906
907// Sign extends.
Krzysztof Parzyszekf2086812017-02-28 22:37:01 +0000908// sext i1->i32
909def: Pat<(i32 (sext I1:$Pu)),
910 (C2_muxii I1:$Pu, -1, 0)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000911
Krzysztof Parzyszekf2086812017-02-28 22:37:01 +0000912// sext i1->i64
913def: Pat<(i64 (sext I1:$Pu)),
914 (A2_combinew (C2_muxii PredRegs:$Pu, -1, 0),
915 (C2_muxii PredRegs:$Pu, -1, 0))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000916
917// Zero extends.
Krzysztof Parzyszekf2086812017-02-28 22:37:01 +0000918// zext i1->i32
919def: Pat<(i32 (zext I1:$Pu)),
920 (C2_muxii PredRegs:$Pu, 1, 0)>;
921
922// zext i1->i64
923def: Pat<(i64 (zext I1:$Pu)),
924 (ToZext64 (C2_muxii PredRegs:$Pu, 1, 0))>;
925
926// zext i32->i64
927def: Pat<(Zext64 I32:$Rs),
928 (ToZext64 IntRegs:$Rs)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000929
930// Map from Rs = Pd to Pd = mux(Pd, #1, #0)
Krzysztof Parzyszekf2086812017-02-28 22:37:01 +0000931def: Pat<(i32 (anyext I1:$Pu)),
932 (C2_muxii PredRegs:$Pu, 1, 0)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000933
Krzysztof Parzyszekf2086812017-02-28 22:37:01 +0000934// Map from Rss = Pd to Rdd = combine(#0, (mux(Pd, #1, #0)))
935def: Pat<(i64 (anyext I1:$Pu)),
936 (ToZext64 (C2_muxii PredRegs:$Pu, 1, 0))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000937
938// Clear the sign bit in a 64-bit register.
939def ClearSign : OutPatFrag<(ops node:$Rss),
940 (A2_combinew (S2_clrbit_i (HiReg $Rss), 31), (LoReg $Rss))>;
941
942def MulHU : OutPatFrag<(ops node:$Rss, node:$Rtt),
943 (A2_addp
944 (M2_dpmpyuu_acc_s0
945 (S2_lsr_i_p
946 (A2_addp
947 (M2_dpmpyuu_acc_s0
948 (S2_lsr_i_p (M2_dpmpyuu_s0 (LoReg $Rss), (LoReg $Rtt)), 32),
949 (HiReg $Rss),
950 (LoReg $Rtt)),
951 (A2_combinew (A2_tfrsi 0),
952 (LoReg (M2_dpmpyuu_s0 (LoReg $Rss), (HiReg $Rtt))))),
953 32),
954 (HiReg $Rss),
955 (HiReg $Rtt)),
956 (S2_lsr_i_p (M2_dpmpyuu_s0 (LoReg $Rss), (HiReg $Rtt)), 32))>;
957
958// Multiply 64-bit unsigned and use upper result.
959def : Pat <(mulhu I64:$Rss, I64:$Rtt), (MulHU $Rss, $Rtt)>;
960
961// Multiply 64-bit signed and use upper result.
962//
963// For two signed 64-bit integers A and B, let A' and B' denote A and B
964// with the sign bit cleared. Then A = -2^63*s(A) + A', where s(A) is the
965// sign bit of A (and identically for B). With this notation, the signed
966// product A*B can be written as:
967// AB = (-2^63 s(A) + A') * (-2^63 s(B) + B')
968// = 2^126 s(A)s(B) - 2^63 [s(A)B'+s(B)A'] + A'B'
969// = 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']
970// = (unsigned product AB) - 2^64 [s(A)B'+s(B)A']
971
972def : Pat <(mulhs I64:$Rss, I64:$Rtt),
973 (A2_subp
974 (MulHU $Rss, $Rtt),
975 (A2_addp
976 (A2_andp (S2_asr_i_p $Rss, 63), (ClearSign $Rtt)),
977 (A2_andp (S2_asr_i_p $Rtt, 63), (ClearSign $Rss))))>;
978
979// Hexagon specific ISD nodes.
980def SDTHexagonALLOCA : SDTypeProfile<1, 2,
981 [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
982def HexagonALLOCA : SDNode<"HexagonISD::ALLOCA", SDTHexagonALLOCA,
983 [SDNPHasChain]>;
984
985
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000986def: Pat<(HexagonALLOCA I32:$Rs, (i32 imm:$A)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000987 (PS_alloca IntRegs:$Rs, imm:$A)>;
988
989def HexagonJT: SDNode<"HexagonISD::JT", SDTIntUnaryOp>;
990def HexagonCP: SDNode<"HexagonISD::CP", SDTIntUnaryOp>;
991
992def: Pat<(HexagonJT tjumptable:$dst), (A2_tfrsi imm:$dst)>;
993def: Pat<(HexagonCP tconstpool:$dst), (A2_tfrsi imm:$dst)>;
994
995let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000996def: Pat<(add I32:$src1, (sra I32:$Rs, u5_0ImmPred:$u5)), (S2_asr_i_r_acc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
997def: Pat<(sub I32:$src1, (sra I32:$Rs, u5_0ImmPred:$u5)), (S2_asr_i_r_nac IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
998def: Pat<(and I32:$src1, (sra I32:$Rs, u5_0ImmPred:$u5)), (S2_asr_i_r_and IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
999def: Pat<(or I32:$src1, (sra I32:$Rs, u5_0ImmPred:$u5)), (S2_asr_i_r_or IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001000
1001let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001002def: Pat<(add I64:$src1, (sra I64:$Rs, u6_0ImmPred:$u5)), (S2_asr_i_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1003def: Pat<(sub I64:$src1, (sra I64:$Rs, u6_0ImmPred:$u5)), (S2_asr_i_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1004def: Pat<(and I64:$src1, (sra I64:$Rs, u6_0ImmPred:$u5)), (S2_asr_i_p_and DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1005def: Pat<(or I64:$src1, (sra I64:$Rs, u6_0ImmPred:$u5)), (S2_asr_i_p_or DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001006
1007let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001008def: Pat<(add I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_acc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1009def: Pat<(sub I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_nac IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1010def: Pat<(and I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_and IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1011def: Pat<(or I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_or IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001012let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001013def: Pat<(xor I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_xacc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001014
1015let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001016def: Pat<(add I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1017def: Pat<(sub I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1018def: Pat<(and I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_and DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1019def: Pat<(or I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_or DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001020let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001021def: Pat<(xor I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_xacc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001022
1023let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001024def: Pat<(add I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_acc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1025def: Pat<(sub I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_nac IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1026def: Pat<(and I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_and IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1027def: Pat<(or I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_or IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001028let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001029def: Pat<(xor I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_xacc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001030
1031let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001032def: Pat<(add I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1033def: Pat<(sub I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1034def: Pat<(and I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_and DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1035def: Pat<(or I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_or DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001036let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001037def: Pat<(xor I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_xacc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001038
1039let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001040def: Pat<(add I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_asl_r_r_acc IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1041def: Pat<(sub I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_asl_r_r_nac IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1042def: Pat<(and I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_asl_r_r_and IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1043def: Pat<(or I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_asl_r_r_or IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001044let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001045def: Pat<(add I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1046def: Pat<(sub I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1047def: Pat<(and I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_and DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1048def: Pat<(or I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_or DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1049def: Pat<(xor I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_xor DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001050
1051let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001052def: Pat<(add I32:$src1, (sra I32:$Rs, I32:$Rt)), (S2_asr_r_r_acc IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1053def: Pat<(sub I32:$src1, (sra I32:$Rs, I32:$Rt)), (S2_asr_r_r_nac IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1054def: Pat<(and I32:$src1, (sra I32:$Rs, I32:$Rt)), (S2_asr_r_r_and IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1055def: Pat<(or I32:$src1, (sra I32:$Rs, I32:$Rt)), (S2_asr_r_r_or IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001056let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001057def: Pat<(add I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1058def: Pat<(sub I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1059def: Pat<(and I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_and DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1060def: Pat<(or I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_or DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1061def: Pat<(xor I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_xor DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001062
1063let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001064def: Pat<(add I32:$src1, (srl I32:$Rs, I32:$Rt)), (S2_lsr_r_r_acc IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1065def: Pat<(sub I32:$src1, (srl I32:$Rs, I32:$Rt)), (S2_lsr_r_r_nac IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1066def: Pat<(and I32:$src1, (srl I32:$Rs, I32:$Rt)), (S2_lsr_r_r_and IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1067def: Pat<(or I32:$src1, (srl I32:$Rs, I32:$Rt)), (S2_lsr_r_r_or IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001068let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001069def: Pat<(add I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1070def: Pat<(sub I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1071def: Pat<(and I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_and DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1072def: Pat<(or I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_or DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1073def: Pat<(xor I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_xor DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001074
1075let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001076def: Pat<(add I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_lsl_r_r_acc IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1077def: Pat<(sub I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_lsl_r_r_nac IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1078def: Pat<(and I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_lsl_r_r_and IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1079def: Pat<(or I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_lsl_r_r_or IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001080let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001081def: Pat<(add I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1082def: Pat<(sub I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1083def: Pat<(and I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_and DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1084def: Pat<(or I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_or DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1085def: Pat<(xor I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_xor DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001086
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001087def: Pat<(sra I64:$src1, I32:$src2), (S2_asr_r_p DoubleRegs:$src1, IntRegs:$src2)>;
1088def: Pat<(srl I64:$src1, I32:$src2), (S2_lsr_r_p DoubleRegs:$src1, IntRegs:$src2)>;
1089def: Pat<(shl I64:$src1, I32:$src2), (S2_asl_r_p DoubleRegs:$src1, IntRegs:$src2)>;
1090def: Pat<(shl I64:$src1, I32:$src2), (S2_lsl_r_p DoubleRegs:$src1, IntRegs:$src2)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001091
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001092def: Pat<(sra I32:$src1, I32:$src2), (S2_asr_r_r IntRegs:$src1, IntRegs:$src2)>;
1093def: Pat<(srl I32:$src1, I32:$src2), (S2_lsr_r_r IntRegs:$src1, IntRegs:$src2)>;
1094def: Pat<(shl I32:$src1, I32:$src2), (S2_asl_r_r IntRegs:$src1, IntRegs:$src2)>;
1095def: Pat<(shl I32:$src1, I32:$src2), (S2_lsl_r_r IntRegs:$src1, IntRegs:$src2)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001096
1097def SDTHexagonINSERT:
1098 SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
1099 SDTCisInt<0>, SDTCisVT<3, i32>, SDTCisVT<4, i32>]>;
1100def SDTHexagonINSERTRP:
1101 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
1102 SDTCisInt<0>, SDTCisVT<3, i64>]>;
1103
1104def HexagonINSERT : SDNode<"HexagonISD::INSERT", SDTHexagonINSERT>;
1105def HexagonINSERTRP : SDNode<"HexagonISD::INSERTRP", SDTHexagonINSERTRP>;
1106
1107def: Pat<(HexagonINSERT I32:$Rs, I32:$Rt, u5_0ImmPred:$u1, u5_0ImmPred:$u2),
1108 (S2_insert I32:$Rs, I32:$Rt, u5_0ImmPred:$u1, u5_0ImmPred:$u2)>;
1109def: Pat<(HexagonINSERT I64:$Rs, I64:$Rt, u6_0ImmPred:$u1, u6_0ImmPred:$u2),
1110 (S2_insertp I64:$Rs, I64:$Rt, u6_0ImmPred:$u1, u6_0ImmPred:$u2)>;
1111def: Pat<(HexagonINSERTRP I32:$Rs, I32:$Rt, I64:$Ru),
1112 (S2_insert_rp I32:$Rs, I32:$Rt, I64:$Ru)>;
1113def: Pat<(HexagonINSERTRP I64:$Rs, I64:$Rt, I64:$Ru),
1114 (S2_insertp_rp I64:$Rs, I64:$Rt, I64:$Ru)>;
1115
1116let AddedComplexity = 100 in
1117def: Pat<(or (or (shl (HexagonINSERT (i32 (zextloadi8 (add I32:$b, 2))),
1118 (i32 (extloadi8 (add I32:$b, 3))),
1119 24, 8),
1120 (i32 16)),
1121 (shl (i32 (zextloadi8 (add I32:$b, 1))), (i32 8))),
1122 (zextloadi8 I32:$b)),
1123 (A2_swiz (L2_loadri_io I32:$b, 0))>;
1124
1125def SDTHexagonEXTRACTU:
1126 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<1>,
1127 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
1128def SDTHexagonEXTRACTURP:
1129 SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<1>,
1130 SDTCisVT<2, i64>]>;
1131
1132def HexagonEXTRACTU : SDNode<"HexagonISD::EXTRACTU", SDTHexagonEXTRACTU>;
1133def HexagonEXTRACTURP : SDNode<"HexagonISD::EXTRACTURP", SDTHexagonEXTRACTURP>;
1134
1135def: Pat<(HexagonEXTRACTU I32:$src1, u5_0ImmPred:$src2, u5_0ImmPred:$src3),
1136 (S2_extractu I32:$src1, u5_0ImmPred:$src2, u5_0ImmPred:$src3)>;
1137def: Pat<(HexagonEXTRACTU I64:$src1, u6_0ImmPred:$src2, u6_0ImmPred:$src3),
1138 (S2_extractup I64:$src1, u6_0ImmPred:$src2, u6_0ImmPred:$src3)>;
1139def: Pat<(HexagonEXTRACTURP I32:$src1, I64:$src2),
1140 (S2_extractu_rp I32:$src1, I64:$src2)>;
1141def: Pat<(HexagonEXTRACTURP I64:$src1, I64:$src2),
1142 (S2_extractup_rp I64:$src1, I64:$src2)>;
1143
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00001144def n8_0ImmPred: PatLeaf<(i32 imm), [{
1145 int64_t V = N->getSExtValue();
1146 return -255 <= V && V <= 0;
1147}]>;
1148
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001149// Change the sign of the immediate for Rd=-mpyi(Rs,#u8)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001150def: Pat<(mul I32:$src1, (ineg n8_0ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001151 (M2_mpysin IntRegs:$src1, u8_0ImmPred:$src2)>;
1152
1153multiclass MinMax_pats_p<PatFrag Op, InstHexagon Inst, InstHexagon SwapInst> {
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +00001154 defm: T_MinMax_pats<Op, I64, Inst, SwapInst>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001155}
1156
Krzysztof Parzyszekef580172017-05-30 17:47:51 +00001157def: Pat<(add Sext64:$Rs, I64:$Rt),
1158 (A2_addsp (LoReg Sext64:$Rs), DoubleRegs:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001159
1160let AddedComplexity = 200 in {
1161 defm: MinMax_pats_p<setge, A2_maxp, A2_minp>;
1162 defm: MinMax_pats_p<setgt, A2_maxp, A2_minp>;
1163 defm: MinMax_pats_p<setle, A2_minp, A2_maxp>;
1164 defm: MinMax_pats_p<setlt, A2_minp, A2_maxp>;
1165 defm: MinMax_pats_p<setuge, A2_maxup, A2_minup>;
1166 defm: MinMax_pats_p<setugt, A2_maxup, A2_minup>;
1167 defm: MinMax_pats_p<setule, A2_minup, A2_maxup>;
1168 defm: MinMax_pats_p<setult, A2_minup, A2_maxup>;
1169}
1170
1171def callv3 : SDNode<"HexagonISD::CALL", SDT_SPCall,
1172 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;
1173
1174def callv3nr : SDNode<"HexagonISD::CALLnr", SDT_SPCall,
1175 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;
1176
1177
1178// Map call instruction
1179def : Pat<(callv3 I32:$dst),
1180 (J2_callr I32:$dst)>;
1181def : Pat<(callv3 tglobaladdr:$dst),
1182 (J2_call tglobaladdr:$dst)>;
1183def : Pat<(callv3 texternalsym:$dst),
1184 (J2_call texternalsym:$dst)>;
1185def : Pat<(callv3 tglobaltlsaddr:$dst),
1186 (J2_call tglobaltlsaddr:$dst)>;
1187
1188def : Pat<(callv3nr I32:$dst),
1189 (PS_callr_nr I32:$dst)>;
1190def : Pat<(callv3nr tglobaladdr:$dst),
1191 (PS_call_nr tglobaladdr:$dst)>;
1192def : Pat<(callv3nr texternalsym:$dst),
1193 (PS_call_nr texternalsym:$dst)>;
1194
1195
1196def addrga: PatLeaf<(i32 AddrGA:$Addr)>;
1197def addrgp: PatLeaf<(i32 AddrGP:$Addr)>;
1198
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001199
1200// Pats for instruction selection.
1201
1202// A class to embed the usual comparison patfrags within a zext to i32.
1203// The seteq/setne frags use "lhs" and "rhs" as operands, so use the same
1204// names, or else the frag's "body" won't match the operands.
1205class CmpInReg<PatFrag Op>
1206 : PatFrag<(ops node:$lhs, node:$rhs),(i32 (zext (i1 Op.Fragment)))>;
1207
1208def: T_cmp32_rr_pat<A4_rcmpeq, CmpInReg<seteq>, i32>;
1209def: T_cmp32_rr_pat<A4_rcmpneq, CmpInReg<setne>, i32>;
1210
1211def: T_cmp32_rr_pat<C4_cmpneq, setne, i1>;
1212def: T_cmp32_rr_pat<C4_cmplte, setle, i1>;
1213def: T_cmp32_rr_pat<C4_cmplteu, setule, i1>;
1214
1215def: T_cmp32_rr_pat<C4_cmplte, RevCmp<setge>, i1>;
1216def: T_cmp32_rr_pat<C4_cmplteu, RevCmp<setuge>, i1>;
1217
1218let AddedComplexity = 100 in {
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001219 def: Pat<(i1 (seteq (and (xor I32:$Rs, I32:$Rt),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001220 255), 0)),
1221 (A4_cmpbeq IntRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001222 def: Pat<(i1 (setne (and (xor I32:$Rs, I32:$Rt),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001223 255), 0)),
1224 (C2_not (A4_cmpbeq IntRegs:$Rs, IntRegs:$Rt))>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001225 def: Pat<(i1 (seteq (and (xor I32:$Rs, I32:$Rt),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001226 65535), 0)),
1227 (A4_cmpheq IntRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001228 def: Pat<(i1 (setne (and (xor I32:$Rs, I32:$Rt),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001229 65535), 0)),
1230 (C2_not (A4_cmpheq IntRegs:$Rs, IntRegs:$Rt))>;
1231}
1232
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001233def: Pat<(i32 (zext (i1 (seteq I32:$Rs, s32_0ImmPred:$s8)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001234 (A4_rcmpeqi IntRegs:$Rs, s32_0ImmPred:$s8)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001235def: Pat<(i32 (zext (i1 (setne I32:$Rs, s32_0ImmPred:$s8)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001236 (A4_rcmpneqi IntRegs:$Rs, s32_0ImmPred:$s8)>;
1237
1238// Preserve the S2_tstbit_r generation
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001239def: Pat<(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, I32:$src2)),
1240 I32:$src1)), 0)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001241 (C2_muxii (S2_tstbit_r IntRegs:$src1, IntRegs:$src2), 1, 0)>;
1242
1243// The complexity of the combines involving immediates should be greater
1244// than the complexity of the combine with two registers.
1245let AddedComplexity = 50 in {
1246def: Pat<(HexagonCOMBINE IntRegs:$r, s32_0ImmPred:$i),
1247 (A4_combineri IntRegs:$r, s32_0ImmPred:$i)>;
1248
1249def: Pat<(HexagonCOMBINE s32_0ImmPred:$i, IntRegs:$r),
1250 (A4_combineir s32_0ImmPred:$i, IntRegs:$r)>;
1251}
1252
1253// The complexity of the combine with two immediates should be greater than
1254// the complexity of a combine involving a register.
1255let AddedComplexity = 75 in {
1256def: Pat<(HexagonCOMBINE s8_0ImmPred:$s8, u32_0ImmPred:$u6),
1257 (A4_combineii imm:$s8, imm:$u6)>;
1258def: Pat<(HexagonCOMBINE s32_0ImmPred:$s8, s8_0ImmPred:$S8),
1259 (A2_combineii imm:$s8, imm:$S8)>;
1260}
1261
1262
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001263// Patterns to generate indexed loads with different forms of the address:
1264// - frameindex,
1265// - base + offset,
1266// - base (without offset).
1267multiclass Loadxm_pat<PatFrag Load, ValueType VT, PatFrag ValueMod,
1268 PatLeaf ImmPred, InstHexagon MI> {
1269 def: Pat<(VT (Load AddrFI:$fi)),
1270 (VT (ValueMod (MI AddrFI:$fi, 0)))>;
1271 def: Pat<(VT (Load (add AddrFI:$fi, ImmPred:$Off))),
1272 (VT (ValueMod (MI AddrFI:$fi, imm:$Off)))>;
1273 def: Pat<(VT (Load (add IntRegs:$Rs, ImmPred:$Off))),
1274 (VT (ValueMod (MI IntRegs:$Rs, imm:$Off)))>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001275 def: Pat<(VT (Load I32:$Rs)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001276 (VT (ValueMod (MI IntRegs:$Rs, 0)))>;
1277}
1278
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001279defm: Loadxm_pat<extloadi1, i64, ToZext64, s32_0ImmPred, L2_loadrub_io>;
1280defm: Loadxm_pat<extloadi8, i64, ToZext64, s32_0ImmPred, L2_loadrub_io>;
1281defm: Loadxm_pat<extloadi16, i64, ToZext64, s31_1ImmPred, L2_loadruh_io>;
1282defm: Loadxm_pat<zextloadi1, i64, ToZext64, s32_0ImmPred, L2_loadrub_io>;
1283defm: Loadxm_pat<zextloadi8, i64, ToZext64, s32_0ImmPred, L2_loadrub_io>;
1284defm: Loadxm_pat<zextloadi16, i64, ToZext64, s31_1ImmPred, L2_loadruh_io>;
1285defm: Loadxm_pat<sextloadi8, i64, ToSext64, s32_0ImmPred, L2_loadrb_io>;
1286defm: Loadxm_pat<sextloadi16, i64, ToSext64, s31_1ImmPred, L2_loadrh_io>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001287
1288// Map Rdd = anyext(Rs) -> Rdd = combine(#0, Rs).
Krzysztof Parzyszek84755102016-11-06 17:56:48 +00001289def: Pat<(Aext64 I32:$src1), (ToZext64 IntRegs:$src1)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001290
1291multiclass T_LoadAbsReg_Pat <PatFrag ldOp, InstHexagon MI, ValueType VT = i32> {
1292 def : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2_0ImmPred:$src2),
1293 (HexagonCONST32 tglobaladdr:$src3)))),
1294 (MI IntRegs:$src1, u2_0ImmPred:$src2, tglobaladdr:$src3)>;
1295 def : Pat <(VT (ldOp (add IntRegs:$src1,
1296 (HexagonCONST32 tglobaladdr:$src2)))),
1297 (MI IntRegs:$src1, 0, tglobaladdr:$src2)>;
1298
1299 def : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2_0ImmPred:$src2),
1300 (HexagonCONST32 tconstpool:$src3)))),
1301 (MI IntRegs:$src1, u2_0ImmPred:$src2, tconstpool:$src3)>;
1302 def : Pat <(VT (ldOp (add IntRegs:$src1,
1303 (HexagonCONST32 tconstpool:$src2)))),
1304 (MI IntRegs:$src1, 0, tconstpool:$src2)>;
1305
1306 def : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2_0ImmPred:$src2),
1307 (HexagonCONST32 tjumptable:$src3)))),
1308 (MI IntRegs:$src1, u2_0ImmPred:$src2, tjumptable:$src3)>;
1309 def : Pat <(VT (ldOp (add IntRegs:$src1,
1310 (HexagonCONST32 tjumptable:$src2)))),
1311 (MI IntRegs:$src1, 0, tjumptable:$src2)>;
1312}
1313
1314let AddedComplexity = 60 in {
1315defm : T_LoadAbsReg_Pat <sextloadi8, L4_loadrb_ur>;
1316defm : T_LoadAbsReg_Pat <zextloadi8, L4_loadrub_ur>;
1317defm : T_LoadAbsReg_Pat <extloadi8, L4_loadrub_ur>;
1318
1319defm : T_LoadAbsReg_Pat <sextloadi16, L4_loadrh_ur>;
1320defm : T_LoadAbsReg_Pat <zextloadi16, L4_loadruh_ur>;
1321defm : T_LoadAbsReg_Pat <extloadi16, L4_loadruh_ur>;
1322
1323defm : T_LoadAbsReg_Pat <load, L4_loadri_ur>;
1324defm : T_LoadAbsReg_Pat <load, L4_loadrd_ur, i64>;
1325}
1326
1327// 'def pats' for load instructions with base + register offset and non-zero
1328// immediate value. Immediate value is used to left-shift the second
1329// register operand.
1330class Loadxs_pat<PatFrag Load, ValueType VT, InstHexagon MI>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001331 : Pat<(VT (Load (add I32:$Rs,
1332 (i32 (shl I32:$Rt, u2_0ImmPred:$u2))))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001333 (VT (MI IntRegs:$Rs, IntRegs:$Rt, imm:$u2))>;
1334
1335let AddedComplexity = 40 in {
1336 def: Loadxs_pat<extloadi8, i32, L4_loadrub_rr>;
1337 def: Loadxs_pat<zextloadi8, i32, L4_loadrub_rr>;
1338 def: Loadxs_pat<sextloadi8, i32, L4_loadrb_rr>;
1339 def: Loadxs_pat<extloadi16, i32, L4_loadruh_rr>;
1340 def: Loadxs_pat<zextloadi16, i32, L4_loadruh_rr>;
1341 def: Loadxs_pat<sextloadi16, i32, L4_loadrh_rr>;
1342 def: Loadxs_pat<load, i32, L4_loadri_rr>;
1343 def: Loadxs_pat<load, i64, L4_loadrd_rr>;
1344}
1345
1346// 'def pats' for load instruction base + register offset and
1347// zero immediate value.
1348class Loadxs_simple_pat<PatFrag Load, ValueType VT, InstHexagon MI>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001349 : Pat<(VT (Load (add I32:$Rs, I32:$Rt))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001350 (VT (MI IntRegs:$Rs, IntRegs:$Rt, 0))>;
1351
1352let AddedComplexity = 20 in {
1353 def: Loadxs_simple_pat<extloadi8, i32, L4_loadrub_rr>;
1354 def: Loadxs_simple_pat<zextloadi8, i32, L4_loadrub_rr>;
1355 def: Loadxs_simple_pat<sextloadi8, i32, L4_loadrb_rr>;
1356 def: Loadxs_simple_pat<extloadi16, i32, L4_loadruh_rr>;
1357 def: Loadxs_simple_pat<zextloadi16, i32, L4_loadruh_rr>;
1358 def: Loadxs_simple_pat<sextloadi16, i32, L4_loadrh_rr>;
1359 def: Loadxs_simple_pat<load, i32, L4_loadri_rr>;
1360 def: Loadxs_simple_pat<load, i64, L4_loadrd_rr>;
1361}
1362
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001363let AddedComplexity = 40 in
1364multiclass T_StoreAbsReg_Pats <InstHexagon MI, RegisterClass RC, ValueType VT,
1365 PatFrag stOp> {
1366 def : Pat<(stOp (VT RC:$src4),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001367 (add (shl I32:$src1, u2_0ImmPred:$src2),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001368 u32_0ImmPred:$src3)),
1369 (MI IntRegs:$src1, u2_0ImmPred:$src2, u32_0ImmPred:$src3, RC:$src4)>;
1370
1371 def : Pat<(stOp (VT RC:$src4),
1372 (add (shl IntRegs:$src1, u2_0ImmPred:$src2),
1373 (HexagonCONST32 tglobaladdr:$src3))),
1374 (MI IntRegs:$src1, u2_0ImmPred:$src2, tglobaladdr:$src3, RC:$src4)>;
1375
1376 def : Pat<(stOp (VT RC:$src4),
1377 (add IntRegs:$src1, (HexagonCONST32 tglobaladdr:$src3))),
1378 (MI IntRegs:$src1, 0, tglobaladdr:$src3, RC:$src4)>;
1379}
1380
1381defm : T_StoreAbsReg_Pats <S4_storerd_ur, DoubleRegs, i64, store>;
1382defm : T_StoreAbsReg_Pats <S4_storeri_ur, IntRegs, i32, store>;
1383defm : T_StoreAbsReg_Pats <S4_storerb_ur, IntRegs, i32, truncstorei8>;
1384defm : T_StoreAbsReg_Pats <S4_storerh_ur, IntRegs, i32, truncstorei16>;
1385
1386class Storexs_pat<PatFrag Store, PatFrag Value, InstHexagon MI>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001387 : Pat<(Store Value:$Ru, (add I32:$Rs,
1388 (i32 (shl I32:$Rt, u2_0ImmPred:$u2)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001389 (MI IntRegs:$Rs, IntRegs:$Rt, imm:$u2, Value:$Ru)>;
1390
1391let AddedComplexity = 40 in {
1392 def: Storexs_pat<truncstorei8, I32, S4_storerb_rr>;
1393 def: Storexs_pat<truncstorei16, I32, S4_storerh_rr>;
1394 def: Storexs_pat<store, I32, S4_storeri_rr>;
1395 def: Storexs_pat<store, I64, S4_storerd_rr>;
1396}
1397
1398def s30_2ProperPred : PatLeaf<(i32 imm), [{
1399 int64_t v = (int64_t)N->getSExtValue();
1400 return isShiftedInt<30,2>(v) && !isShiftedInt<29,3>(v);
1401}]>;
1402def RoundTo8 : SDNodeXForm<imm, [{
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00001403 int32_t Imm = N->getSExtValue();
1404 return CurDAG->getTargetConstant(Imm & -8, SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001405}]>;
1406
1407let AddedComplexity = 40 in
1408def: Pat<(store I64:$Ru, (add I32:$Rs, s30_2ProperPred:$Off)),
1409 (S2_storerd_io (A2_addi I32:$Rs, 4), (RoundTo8 $Off), I64:$Ru)>;
1410
1411class Store_rr_pat<PatFrag Store, PatFrag Value, InstHexagon MI>
1412 : Pat<(Store Value:$Ru, (add I32:$Rs, I32:$Rt)),
1413 (MI IntRegs:$Rs, IntRegs:$Rt, 0, Value:$Ru)>;
1414
1415let AddedComplexity = 20 in {
1416 def: Store_rr_pat<truncstorei8, I32, S4_storerb_rr>;
1417 def: Store_rr_pat<truncstorei16, I32, S4_storerh_rr>;
1418 def: Store_rr_pat<store, I32, S4_storeri_rr>;
1419 def: Store_rr_pat<store, I64, S4_storerd_rr>;
1420}
1421
1422
1423def IMM_BYTE : SDNodeXForm<imm, [{
1424 // -1 etc is represented as 255 etc
1425 // assigning to a byte restores our desired signed value.
1426 int8_t imm = N->getSExtValue();
1427 return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32);
1428}]>;
1429
1430def IMM_HALF : SDNodeXForm<imm, [{
1431 // -1 etc is represented as 65535 etc
1432 // assigning to a short restores our desired signed value.
1433 int16_t imm = N->getSExtValue();
1434 return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32);
1435}]>;
1436
1437def IMM_WORD : SDNodeXForm<imm, [{
1438 // -1 etc can be represented as 4294967295 etc
1439 // Currently, it's not doing this. But some optimization
1440 // might convert -1 to a large +ve number.
1441 // assigning to a word restores our desired signed value.
1442 int32_t imm = N->getSExtValue();
1443 return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32);
1444}]>;
1445
1446def ToImmByte : OutPatFrag<(ops node:$R), (IMM_BYTE $R)>;
1447def ToImmHalf : OutPatFrag<(ops node:$R), (IMM_HALF $R)>;
1448def ToImmWord : OutPatFrag<(ops node:$R), (IMM_WORD $R)>;
1449
1450// Emit store-immediate, but only when the stored value will not be constant-
1451// extended. The reason for that is that there is no pass that can optimize
1452// constant extenders in store-immediate instructions. In some cases we can
1453// end up will a number of such stores, all of which store the same extended
1454// value (e.g. after unrolling a loop that initializes floating point array).
1455
1456// Predicates to determine if the 16-bit immediate is expressible as a sign-
1457// extended 8-bit immediate. Store-immediate-halfword will ignore any bits
1458// beyond 0..15, so we don't care what is in there.
1459
1460def i16in8ImmPred: PatLeaf<(i32 imm), [{
1461 int64_t v = (int16_t)N->getSExtValue();
1462 return v == (int64_t)(int8_t)v;
1463}]>;
1464
1465// Predicates to determine if the 32-bit immediate is expressible as a sign-
1466// extended 8-bit immediate.
1467def i32in8ImmPred: PatLeaf<(i32 imm), [{
1468 int64_t v = (int32_t)N->getSExtValue();
1469 return v == (int64_t)(int8_t)v;
1470}]>;
1471
1472
1473let AddedComplexity = 40 in {
1474 // Even though the offset is not extendable in the store-immediate, we
1475 // can still generate the fi# in the base address. If the final offset
1476 // is not valid for the instruction, we will replace it with a scratch
1477 // register.
1478// def: Storexm_fi_pat <truncstorei8, s32_0ImmPred, ToImmByte, S4_storeirb_io>;
1479// def: Storexm_fi_pat <truncstorei16, i16in8ImmPred, ToImmHalf,
1480// S4_storeirh_io>;
1481// def: Storexm_fi_pat <store, i32in8ImmPred, ToImmWord, S4_storeiri_io>;
1482
1483// defm: Storexm_fi_add_pat <truncstorei8, s32_0ImmPred, u6_0ImmPred, ToImmByte,
1484// S4_storeirb_io>;
1485// defm: Storexm_fi_add_pat <truncstorei16, i16in8ImmPred, u6_1ImmPred,
1486// ToImmHalf, S4_storeirh_io>;
1487// defm: Storexm_fi_add_pat <store, i32in8ImmPred, u6_2ImmPred, ToImmWord,
1488// S4_storeiri_io>;
1489
1490 defm: Storexm_add_pat<truncstorei8, s32_0ImmPred, u6_0ImmPred, ToImmByte,
1491 S4_storeirb_io>;
1492 defm: Storexm_add_pat<truncstorei16, i16in8ImmPred, u6_1ImmPred, ToImmHalf,
1493 S4_storeirh_io>;
1494 defm: Storexm_add_pat<store, i32in8ImmPred, u6_2ImmPred, ToImmWord,
1495 S4_storeiri_io>;
1496}
1497
1498def: Storexm_simple_pat<truncstorei8, s32_0ImmPred, ToImmByte, S4_storeirb_io>;
1499def: Storexm_simple_pat<truncstorei16, s32_0ImmPred, ToImmHalf, S4_storeirh_io>;
1500def: Storexm_simple_pat<store, s32_0ImmPred, ToImmWord, S4_storeiri_io>;
1501
1502// op(Ps, op(Pt, Pu))
1503class LogLog_pat<SDNode Op1, SDNode Op2, InstHexagon MI>
1504 : Pat<(i1 (Op1 I1:$Ps, (Op2 I1:$Pt, I1:$Pu))),
1505 (MI I1:$Ps, I1:$Pt, I1:$Pu)>;
1506
1507// op(Ps, op(Pt, ~Pu))
1508class LogLogNot_pat<SDNode Op1, SDNode Op2, InstHexagon MI>
1509 : Pat<(i1 (Op1 I1:$Ps, (Op2 I1:$Pt, (not I1:$Pu)))),
1510 (MI I1:$Ps, I1:$Pt, I1:$Pu)>;
1511
1512def: LogLog_pat<and, and, C4_and_and>;
1513def: LogLog_pat<and, or, C4_and_or>;
1514def: LogLog_pat<or, and, C4_or_and>;
1515def: LogLog_pat<or, or, C4_or_or>;
1516
1517def: LogLogNot_pat<and, and, C4_and_andn>;
1518def: LogLogNot_pat<and, or, C4_and_orn>;
1519def: LogLogNot_pat<or, and, C4_or_andn>;
1520def: LogLogNot_pat<or, or, C4_or_orn>;
1521
1522//===----------------------------------------------------------------------===//
1523// PIC: Support for PIC compilations. The patterns and SD nodes defined
1524// below are needed to support code generation for PIC
1525//===----------------------------------------------------------------------===//
1526
1527def SDT_HexagonAtGot
1528 : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i32>]>;
1529def SDT_HexagonAtPcrel
1530 : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
1531
1532// AT_GOT address-of-GOT, address-of-global, offset-in-global
1533def HexagonAtGot : SDNode<"HexagonISD::AT_GOT", SDT_HexagonAtGot>;
1534// AT_PCREL address-of-global
1535def HexagonAtPcrel : SDNode<"HexagonISD::AT_PCREL", SDT_HexagonAtPcrel>;
1536
1537def: Pat<(HexagonAtGot I32:$got, I32:$addr, (i32 0)),
1538 (L2_loadri_io I32:$got, imm:$addr)>;
1539def: Pat<(HexagonAtGot I32:$got, I32:$addr, s30_2ImmPred:$off),
1540 (A2_addi (L2_loadri_io I32:$got, imm:$addr), imm:$off)>;
1541def: Pat<(HexagonAtPcrel I32:$addr),
1542 (C4_addipc imm:$addr)>;
1543
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001544def: Pat<(i64 (and I64:$Rs, (i64 (not I64:$Rt)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001545 (A4_andnp DoubleRegs:$Rs, DoubleRegs:$Rt)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001546def: Pat<(i64 (or I64:$Rs, (i64 (not I64:$Rt)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001547 (A4_ornp DoubleRegs:$Rs, DoubleRegs:$Rt)>;
1548
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001549def: Pat<(add I32:$Rs, (add I32:$Ru, s32_0ImmPred:$s6)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001550 (S4_addaddi IntRegs:$Rs, IntRegs:$Ru, imm:$s6)>;
1551
1552// Rd=add(Rs,sub(#s6,Ru))
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001553def: Pat<(add I32:$src1, (sub s32_0ImmPred:$src2,
1554 I32:$src3)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001555 (S4_subaddi IntRegs:$src1, s32_0ImmPred:$src2, IntRegs:$src3)>;
1556
1557// Rd=sub(add(Rs,#s6),Ru)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001558def: Pat<(sub (add I32:$src1, s32_0ImmPred:$src2),
1559 I32:$src3),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001560 (S4_subaddi IntRegs:$src1, s32_0ImmPred:$src2, IntRegs:$src3)>;
1561
1562// Rd=add(sub(Rs,Ru),#s6)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001563def: Pat<(add (sub I32:$src1, I32:$src3),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001564 (s32_0ImmPred:$src2)),
1565 (S4_subaddi IntRegs:$src1, s32_0ImmPred:$src2, IntRegs:$src3)>;
1566
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001567def: Pat<(xor I64:$dst2,
1568 (xor I64:$Rss, I64:$Rtt)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001569 (M4_xor_xacc DoubleRegs:$dst2, DoubleRegs:$Rss, DoubleRegs:$Rtt)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001570def: Pat<(or I32:$Ru, (and (i32 IntRegs:$_src_), s32_0ImmPred:$s10)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001571 (S4_or_andix IntRegs:$Ru, IntRegs:$_src_, imm:$s10)>;
1572
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001573def: Pat<(or I32:$src1, (and I32:$Rs, s32_0ImmPred:$s10)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001574 (S4_or_andi IntRegs:$src1, IntRegs:$Rs, imm:$s10)>;
1575
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001576def: Pat<(or I32:$src1, (or I32:$Rs, s32_0ImmPred:$s10)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001577 (S4_or_ori IntRegs:$src1, IntRegs:$Rs, imm:$s10)>;
1578
1579
1580
1581// Count trailing zeros: 64-bit.
1582def: Pat<(i32 (trunc (cttz I64:$Rss))), (S2_ct0p I64:$Rss)>;
1583
1584// Count trailing ones: 64-bit.
1585def: Pat<(i32 (trunc (cttz (not I64:$Rss)))), (S2_ct1p I64:$Rss)>;
1586
1587// Define leading/trailing patterns that require zero-extensions to 64 bits.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001588def: Pat<(i64 (ctlz I64:$Rss)), (ToZext64 (S2_cl0p I64:$Rss))>;
1589def: Pat<(i64 (cttz I64:$Rss)), (ToZext64 (S2_ct0p I64:$Rss))>;
1590def: Pat<(i64 (ctlz (not I64:$Rss))), (ToZext64 (S2_cl1p I64:$Rss))>;
1591def: Pat<(i64 (cttz (not I64:$Rss))), (ToZext64 (S2_ct1p I64:$Rss))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001592
Krzysztof Parzyszekaf5ff652017-02-23 15:02:09 +00001593def: Pat<(i64 (ctpop I64:$Rss)), (ToZext64 (S5_popcountp I64:$Rss))>;
1594def: Pat<(i32 (ctpop I32:$Rs)), (S5_popcountp (A4_combineir 0, I32:$Rs))>;
1595
1596def: Pat<(bitreverse I32:$Rs), (S2_brev I32:$Rs)>;
1597def: Pat<(bitreverse I64:$Rss), (S2_brevp I64:$Rss)>;
1598
1599def: Pat<(bswap I32:$Rs), (A2_swiz I32:$Rs)>;
1600def: Pat<(bswap I64:$Rss), (A2_combinew (A2_swiz (LoReg $Rss)),
1601 (A2_swiz (HiReg $Rss)))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001602
1603let AddedComplexity = 20 in { // Complexity greater than cmp reg-imm.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001604 def: Pat<(i1 (seteq (and (shl 1, u5_0ImmPred:$u5), I32:$Rs), 0)),
1605 (S4_ntstbit_i I32:$Rs, u5_0ImmPred:$u5)>;
1606 def: Pat<(i1 (seteq (and (shl 1, I32:$Rt), I32:$Rs), 0)),
1607 (S4_ntstbit_r I32:$Rs, I32:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001608}
1609
1610// Add extra complexity to prefer these instructions over bitsset/bitsclr.
1611// The reason is that tstbit/ntstbit can be folded into a compound instruction:
1612// if ([!]tstbit(...)) jump ...
1613let AddedComplexity = 100 in
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001614def: Pat<(i1 (setne (and I32:$Rs, (i32 IsPow2_32:$u5)), (i32 0))),
1615 (S2_tstbit_i I32:$Rs, (Log2_32 imm:$u5))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001616
1617let AddedComplexity = 100 in
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001618def: Pat<(i1 (seteq (and I32:$Rs, (i32 IsPow2_32:$u5)), (i32 0))),
1619 (S4_ntstbit_i I32:$Rs, (Log2_32 imm:$u5))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001620
1621// Do not increase complexity of these patterns. In the DAG, "cmp i8" may be
1622// represented as a compare against "value & 0xFF", which is an exact match
1623// for cmpb (same for cmph). The patterns below do not contain any additional
1624// complexity that would make them preferable, and if they were actually used
1625// instead of cmpb/cmph, they would result in a compare against register that
1626// is loaded with the byte/half mask (i.e. 0xFF or 0xFFFF).
1627def: Pat<(i1 (setne (and I32:$Rs, u6_0ImmPred:$u6), 0)),
1628 (C4_nbitsclri I32:$Rs, u6_0ImmPred:$u6)>;
1629def: Pat<(i1 (setne (and I32:$Rs, I32:$Rt), 0)),
1630 (C4_nbitsclr I32:$Rs, I32:$Rt)>;
1631def: Pat<(i1 (setne (and I32:$Rs, I32:$Rt), I32:$Rt)),
1632 (C4_nbitsset I32:$Rs, I32:$Rt)>;
1633
1634
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001635def: Pat<(add (mul I32:$Rs, u6_0ImmPred:$U6), u32_0ImmPred:$u6),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001636 (M4_mpyri_addi imm:$u6, IntRegs:$Rs, imm:$U6)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001637def: Pat<(add (mul I32:$Rs, I32:$Rt), u32_0ImmPred:$u6),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001638 (M4_mpyrr_addi imm:$u6, IntRegs:$Rs, IntRegs:$Rt)>;
1639
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001640def: Pat<(add I32:$src1, (mul I32:$src3, u6_2ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001641 (M4_mpyri_addr_u2 IntRegs:$src1, imm:$src2, IntRegs:$src3)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001642def: Pat<(add I32:$src1, (mul I32:$src3, u32_0ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001643 (M4_mpyri_addr IntRegs:$src1, IntRegs:$src3, imm:$src2)>;
1644
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001645def: Pat<(add I32:$Ru, (mul (i32 IntRegs:$_src_), I32:$Rs)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001646 (M4_mpyrr_addr IntRegs:$Ru, IntRegs:$_src_, IntRegs:$Rs)>;
1647
1648def: T_vcmp_pat<A4_vcmpbgt, setgt, v8i8>;
1649
1650class T_Shift_CommOp_pat<InstHexagon MI, SDNode Op, SDNode ShOp>
1651 : Pat<(Op (ShOp IntRegs:$Rx, u5_0ImmPred:$U5), u32_0ImmPred:$u8),
1652 (MI u32_0ImmPred:$u8, IntRegs:$Rx, u5_0ImmPred:$U5)>;
1653
1654let AddedComplexity = 200 in {
1655 def : T_Shift_CommOp_pat <S4_addi_asl_ri, add, shl>;
1656 def : T_Shift_CommOp_pat <S4_addi_lsr_ri, add, srl>;
1657 def : T_Shift_CommOp_pat <S4_andi_asl_ri, and, shl>;
1658 def : T_Shift_CommOp_pat <S4_andi_lsr_ri, and, srl>;
1659}
1660
1661let AddedComplexity = 30 in {
1662 def : T_Shift_CommOp_pat <S4_ori_asl_ri, or, shl>;
1663 def : T_Shift_CommOp_pat <S4_ori_lsr_ri, or, srl>;
1664}
1665
1666class T_Shift_Op_pat<InstHexagon MI, SDNode Op, SDNode ShOp>
1667 : Pat<(Op u32_0ImmPred:$u8, (ShOp IntRegs:$Rx, u5_0ImmPred:$U5)),
1668 (MI u32_0ImmPred:$u8, IntRegs:$Rx, u5_0ImmPred:$U5)>;
1669
1670def : T_Shift_Op_pat <S4_subi_asl_ri, sub, shl>;
1671def : T_Shift_Op_pat <S4_subi_lsr_ri, sub, srl>;
1672
1673let AddedComplexity = 200 in {
1674 def: Pat<(add addrga:$addr, (shl I32:$src2, u5_0ImmPred:$src3)),
1675 (S4_addi_asl_ri addrga:$addr, IntRegs:$src2, u5_0ImmPred:$src3)>;
1676 def: Pat<(add addrga:$addr, (srl I32:$src2, u5_0ImmPred:$src3)),
1677 (S4_addi_lsr_ri addrga:$addr, IntRegs:$src2, u5_0ImmPred:$src3)>;
1678 def: Pat<(sub addrga:$addr, (shl I32:$src2, u5_0ImmPred:$src3)),
1679 (S4_subi_asl_ri addrga:$addr, IntRegs:$src2, u5_0ImmPred:$src3)>;
1680 def: Pat<(sub addrga:$addr, (srl I32:$src2, u5_0ImmPred:$src3)),
1681 (S4_subi_lsr_ri addrga:$addr, IntRegs:$src2, u5_0ImmPred:$src3)>;
1682}
1683
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001684def: Pat<(shl s6_0ImmPred:$s6, I32:$Rt),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001685 (S4_lsli imm:$s6, IntRegs:$Rt)>;
1686
1687
1688//===----------------------------------------------------------------------===//
1689// MEMOP
1690//===----------------------------------------------------------------------===//
1691
1692def m5_0Imm8Pred : PatLeaf<(i32 imm), [{
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00001693 int8_t V = N->getSExtValue();
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001694 return -32 < V && V <= -1;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001695}]>;
1696
1697def m5_0Imm16Pred : PatLeaf<(i32 imm), [{
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00001698 int16_t V = N->getSExtValue();
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001699 return -32 < V && V <= -1;
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00001700}]>;
1701
1702def m5_0ImmPred : PatLeaf<(i32 imm), [{
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001703 int64_t V = N->getSExtValue();
1704 return -31 <= V && V <= -1;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001705}]>;
1706
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001707def IsNPow2_8 : PatLeaf<(i32 imm), [{
1708 uint8_t NV = ~N->getZExtValue();
1709 return isPowerOf2_32(NV);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001710}]>;
1711
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001712def IsNPow2_16 : PatLeaf<(i32 imm), [{
1713 uint16_t NV = ~N->getZExtValue();
1714 return isPowerOf2_32(NV);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001715}]>;
1716
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001717def Log2_8 : SDNodeXForm<imm, [{
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00001718 uint8_t V = N->getZExtValue();
1719 return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001720}]>;
1721
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001722def Log2_16 : SDNodeXForm<imm, [{
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00001723 uint16_t V = N->getZExtValue();
1724 return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001725}]>;
1726
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001727def LogN2_8 : SDNodeXForm<imm, [{
1728 uint8_t NV = ~N->getZExtValue();
1729 return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001730}]>;
1731
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001732def LogN2_16 : SDNodeXForm<imm, [{
1733 uint16_t NV = ~N->getZExtValue();
1734 return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001735}]>;
1736
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001737def NegImm8 : SDNodeXForm<imm, [{
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001738 int8_t NV = -N->getSExtValue();
1739 return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001740}]>;
1741
1742def NegImm16 : SDNodeXForm<imm, [{
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001743 int16_t NV = -N->getSExtValue();
1744 return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001745}]>;
1746
1747def NegImm32 : SDNodeXForm<imm, [{
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001748 int32_t NV = -N->getSExtValue();
1749 return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001750}]>;
1751
1752def IdImm : SDNodeXForm<imm, [{ return SDValue(N, 0); }]>;
1753
1754multiclass Memopxr_simple_pat<PatFrag Load, PatFrag Store, SDNode Oper,
1755 InstHexagon MI> {
1756 // Addr: i32
1757 def: Pat<(Store (Oper (Load I32:$Rs), I32:$A), I32:$Rs),
1758 (MI I32:$Rs, 0, I32:$A)>;
1759 // Addr: fi
1760 def: Pat<(Store (Oper (Load AddrFI:$Rs), I32:$A), AddrFI:$Rs),
1761 (MI AddrFI:$Rs, 0, I32:$A)>;
1762}
1763
1764multiclass Memopxr_add_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred,
1765 SDNode Oper, InstHexagon MI> {
1766 // Addr: i32
1767 def: Pat<(Store (Oper (Load (add I32:$Rs, ImmPred:$Off)), I32:$A),
1768 (add I32:$Rs, ImmPred:$Off)),
1769 (MI I32:$Rs, imm:$Off, I32:$A)>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +00001770 def: Pat<(Store (Oper (Load (IsOrAdd I32:$Rs, ImmPred:$Off)), I32:$A),
1771 (IsOrAdd I32:$Rs, ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001772 (MI I32:$Rs, imm:$Off, I32:$A)>;
1773 // Addr: fi
1774 def: Pat<(Store (Oper (Load (add AddrFI:$Rs, ImmPred:$Off)), I32:$A),
1775 (add AddrFI:$Rs, ImmPred:$Off)),
1776 (MI AddrFI:$Rs, imm:$Off, I32:$A)>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +00001777 def: Pat<(Store (Oper (Load (IsOrAdd AddrFI:$Rs, ImmPred:$Off)), I32:$A),
1778 (IsOrAdd AddrFI:$Rs, ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001779 (MI AddrFI:$Rs, imm:$Off, I32:$A)>;
1780}
1781
1782multiclass Memopxr_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred,
1783 SDNode Oper, InstHexagon MI> {
1784 defm: Memopxr_simple_pat <Load, Store, Oper, MI>;
1785 defm: Memopxr_add_pat <Load, Store, ImmPred, Oper, MI>;
1786}
1787
1788let AddedComplexity = 180 in {
1789 // add reg
1790 defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, add,
1791 /*anyext*/ L4_add_memopb_io>;
1792 defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, add,
1793 /*sext*/ L4_add_memopb_io>;
1794 defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, add,
1795 /*zext*/ L4_add_memopb_io>;
1796 defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, add,
1797 /*anyext*/ L4_add_memoph_io>;
1798 defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, add,
1799 /*sext*/ L4_add_memoph_io>;
1800 defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, add,
1801 /*zext*/ L4_add_memoph_io>;
1802 defm: Memopxr_pat<load, store, u6_2ImmPred, add, L4_add_memopw_io>;
1803
1804 // sub reg
1805 defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, sub,
1806 /*anyext*/ L4_sub_memopb_io>;
1807 defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub,
1808 /*sext*/ L4_sub_memopb_io>;
1809 defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub,
1810 /*zext*/ L4_sub_memopb_io>;
1811 defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, sub,
1812 /*anyext*/ L4_sub_memoph_io>;
1813 defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub,
1814 /*sext*/ L4_sub_memoph_io>;
1815 defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub,
1816 /*zext*/ L4_sub_memoph_io>;
1817 defm: Memopxr_pat<load, store, u6_2ImmPred, sub, L4_sub_memopw_io>;
1818
1819 // and reg
1820 defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, and,
1821 /*anyext*/ L4_and_memopb_io>;
1822 defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, and,
1823 /*sext*/ L4_and_memopb_io>;
1824 defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, and,
1825 /*zext*/ L4_and_memopb_io>;
1826 defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, and,
1827 /*anyext*/ L4_and_memoph_io>;
1828 defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, and,
1829 /*sext*/ L4_and_memoph_io>;
1830 defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, and,
1831 /*zext*/ L4_and_memoph_io>;
1832 defm: Memopxr_pat<load, store, u6_2ImmPred, and, L4_and_memopw_io>;
1833
1834 // or reg
1835 defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, or,
1836 /*anyext*/ L4_or_memopb_io>;
1837 defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, or,
1838 /*sext*/ L4_or_memopb_io>;
1839 defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, or,
1840 /*zext*/ L4_or_memopb_io>;
1841 defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, or,
1842 /*anyext*/ L4_or_memoph_io>;
1843 defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, or,
1844 /*sext*/ L4_or_memoph_io>;
1845 defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, or,
1846 /*zext*/ L4_or_memoph_io>;
1847 defm: Memopxr_pat<load, store, u6_2ImmPred, or, L4_or_memopw_io>;
1848}
1849
1850
1851multiclass Memopxi_simple_pat<PatFrag Load, PatFrag Store, SDNode Oper,
1852 PatFrag Arg, SDNodeXForm ArgMod,
1853 InstHexagon MI> {
1854 // Addr: i32
1855 def: Pat<(Store (Oper (Load I32:$Rs), Arg:$A), I32:$Rs),
1856 (MI I32:$Rs, 0, (ArgMod Arg:$A))>;
1857 // Addr: fi
1858 def: Pat<(Store (Oper (Load AddrFI:$Rs), Arg:$A), AddrFI:$Rs),
1859 (MI AddrFI:$Rs, 0, (ArgMod Arg:$A))>;
1860}
1861
1862multiclass Memopxi_add_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred,
1863 SDNode Oper, PatFrag Arg, SDNodeXForm ArgMod,
1864 InstHexagon MI> {
1865 // Addr: i32
1866 def: Pat<(Store (Oper (Load (add I32:$Rs, ImmPred:$Off)), Arg:$A),
1867 (add I32:$Rs, ImmPred:$Off)),
1868 (MI I32:$Rs, imm:$Off, (ArgMod Arg:$A))>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +00001869 def: Pat<(Store (Oper (Load (IsOrAdd I32:$Rs, ImmPred:$Off)), Arg:$A),
1870 (IsOrAdd I32:$Rs, ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001871 (MI I32:$Rs, imm:$Off, (ArgMod Arg:$A))>;
1872 // Addr: fi
1873 def: Pat<(Store (Oper (Load (add AddrFI:$Rs, ImmPred:$Off)), Arg:$A),
1874 (add AddrFI:$Rs, ImmPred:$Off)),
1875 (MI AddrFI:$Rs, imm:$Off, (ArgMod Arg:$A))>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +00001876 def: Pat<(Store (Oper (Load (IsOrAdd AddrFI:$Rs, ImmPred:$Off)), Arg:$A),
1877 (IsOrAdd AddrFI:$Rs, ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001878 (MI AddrFI:$Rs, imm:$Off, (ArgMod Arg:$A))>;
1879}
1880
1881multiclass Memopxi_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred,
1882 SDNode Oper, PatFrag Arg, SDNodeXForm ArgMod,
1883 InstHexagon MI> {
1884 defm: Memopxi_simple_pat <Load, Store, Oper, Arg, ArgMod, MI>;
1885 defm: Memopxi_add_pat <Load, Store, ImmPred, Oper, Arg, ArgMod, MI>;
1886}
1887
1888
1889let AddedComplexity = 200 in {
1890 // add imm
1891 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, add, u5_0ImmPred,
1892 /*anyext*/ IdImm, L4_iadd_memopb_io>;
1893 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, add, u5_0ImmPred,
1894 /*sext*/ IdImm, L4_iadd_memopb_io>;
1895 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, add, u5_0ImmPred,
1896 /*zext*/ IdImm, L4_iadd_memopb_io>;
1897 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5_0ImmPred,
1898 /*anyext*/ IdImm, L4_iadd_memoph_io>;
1899 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5_0ImmPred,
1900 /*sext*/ IdImm, L4_iadd_memoph_io>;
1901 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5_0ImmPred,
1902 /*zext*/ IdImm, L4_iadd_memoph_io>;
1903 defm: Memopxi_pat<load, store, u6_2ImmPred, add, u5_0ImmPred, IdImm,
1904 L4_iadd_memopw_io>;
1905 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, sub, m5_0Imm8Pred,
1906 /*anyext*/ NegImm8, L4_iadd_memopb_io>;
1907 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub, m5_0Imm8Pred,
1908 /*sext*/ NegImm8, L4_iadd_memopb_io>;
1909 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub, m5_0Imm8Pred,
1910 /*zext*/ NegImm8, L4_iadd_memopb_io>;
1911 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, sub, m5_0Imm16Pred,
1912 /*anyext*/ NegImm16, L4_iadd_memoph_io>;
1913 defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub, m5_0Imm16Pred,
1914 /*sext*/ NegImm16, L4_iadd_memoph_io>;
1915 defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub, m5_0Imm16Pred,
1916 /*zext*/ NegImm16, L4_iadd_memoph_io>;
1917 defm: Memopxi_pat<load, store, u6_2ImmPred, sub, m5_0ImmPred, NegImm32,
1918 L4_iadd_memopw_io>;
1919
1920 // sub imm
1921 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, sub, u5_0ImmPred,
1922 /*anyext*/ IdImm, L4_isub_memopb_io>;
1923 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub, u5_0ImmPred,
1924 /*sext*/ IdImm, L4_isub_memopb_io>;
1925 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub, u5_0ImmPred,
1926 /*zext*/ IdImm, L4_isub_memopb_io>;
1927 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, sub, u5_0ImmPred,
1928 /*anyext*/ IdImm, L4_isub_memoph_io>;
1929 defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub, u5_0ImmPred,
1930 /*sext*/ IdImm, L4_isub_memoph_io>;
1931 defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub, u5_0ImmPred,
1932 /*zext*/ IdImm, L4_isub_memoph_io>;
1933 defm: Memopxi_pat<load, store, u6_2ImmPred, sub, u5_0ImmPred, IdImm,
1934 L4_isub_memopw_io>;
1935 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, add, m5_0Imm8Pred,
1936 /*anyext*/ NegImm8, L4_isub_memopb_io>;
1937 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, add, m5_0Imm8Pred,
1938 /*sext*/ NegImm8, L4_isub_memopb_io>;
1939 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, add, m5_0Imm8Pred,
1940 /*zext*/ NegImm8, L4_isub_memopb_io>;
1941 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, m5_0Imm16Pred,
1942 /*anyext*/ NegImm16, L4_isub_memoph_io>;
1943 defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, add, m5_0Imm16Pred,
1944 /*sext*/ NegImm16, L4_isub_memoph_io>;
1945 defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, add, m5_0Imm16Pred,
1946 /*zext*/ NegImm16, L4_isub_memoph_io>;
1947 defm: Memopxi_pat<load, store, u6_2ImmPred, add, m5_0ImmPred, NegImm32,
1948 L4_isub_memopw_io>;
1949
1950 // clrbit imm
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001951 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, and, IsNPow2_8,
1952 /*anyext*/ LogN2_8, L4_iand_memopb_io>;
1953 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, and, IsNPow2_8,
1954 /*sext*/ LogN2_8, L4_iand_memopb_io>;
1955 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, and, IsNPow2_8,
1956 /*zext*/ LogN2_8, L4_iand_memopb_io>;
1957 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, and, IsNPow2_16,
1958 /*anyext*/ LogN2_16, L4_iand_memoph_io>;
1959 defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, and, IsNPow2_16,
1960 /*sext*/ LogN2_16, L4_iand_memoph_io>;
1961 defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, and, IsNPow2_16,
1962 /*zext*/ LogN2_16, L4_iand_memoph_io>;
1963 defm: Memopxi_pat<load, store, u6_2ImmPred, and, IsNPow2_32,
1964 LogN2_32, L4_iand_memopw_io>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001965
1966 // setbit imm
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001967 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, or, IsPow2_32,
1968 /*anyext*/ Log2_8, L4_ior_memopb_io>;
1969 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, or, IsPow2_32,
1970 /*sext*/ Log2_8, L4_ior_memopb_io>;
1971 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, or, IsPow2_32,
1972 /*zext*/ Log2_8, L4_ior_memopb_io>;
1973 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, or, IsPow2_32,
1974 /*anyext*/ Log2_16, L4_ior_memoph_io>;
1975 defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, or, IsPow2_32,
1976 /*sext*/ Log2_16, L4_ior_memoph_io>;
1977 defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, or, IsPow2_32,
1978 /*zext*/ Log2_16, L4_ior_memoph_io>;
1979 defm: Memopxi_pat<load, store, u6_2ImmPred, or, IsPow2_32,
1980 Log2_32, L4_ior_memopw_io>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001981}
1982
1983def : T_CMP_pat <C4_cmpneqi, setne, s32_0ImmPred>;
1984def : T_CMP_pat <C4_cmpltei, setle, s32_0ImmPred>;
1985def : T_CMP_pat <C4_cmplteui, setule, u9_0ImmPred>;
1986
1987// Map cmplt(Rs, Imm) -> !cmpgt(Rs, Imm-1).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001988def: Pat<(i1 (setlt I32:$src1, s32_0ImmPred:$src2)),
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001989 (C4_cmpltei IntRegs:$src1, (SDEC1 s32_0ImmPred:$src2))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001990
1991// rs != rt -> !(rs == rt).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001992def: Pat<(i1 (setne I32:$src1, s32_0ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001993 (C4_cmpneqi IntRegs:$src1, s32_0ImmPred:$src2)>;
1994
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001995// For the sequence
1996// zext( setult ( and(Rs, 255), u8))
1997// Use the isdigit transformation below
1998
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00001999
2000def u7_0PosImmPred : ImmLeaf<i32, [{
2001 // True if the immediate fits in an 7-bit unsigned field and
2002 // is strictly greater than 0.
2003 return Imm > 0 && isUInt<7>(Imm);
2004}]>;
2005
2006
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002007// Generate code of the form 'C2_muxii(cmpbgtui(Rdd, C-1),0,1)'
2008// for C code of the form r = ((c>='0') & (c<='9')) ? 1 : 0;.
2009// The isdigit transformation relies on two 'clever' aspects:
2010// 1) The data type is unsigned which allows us to eliminate a zero test after
2011// biasing the expression by 48. We are depending on the representation of
2012// the unsigned types, and semantics.
2013// 2) The front end has converted <= 9 into < 10 on entry to LLVM
2014//
2015// For the C code:
2016// retval = ((c>='0') & (c<='9')) ? 1 : 0;
2017// The code is transformed upstream of llvm into
2018// retval = (c-48) < 10 ? 1 : 0;
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00002019
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002020let AddedComplexity = 139 in
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +00002021def: Pat<(i32 (zext (i1 (setult (and I32:$src1, 255), u7_0PosImmPred:$src2)))),
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00002022 (C2_muxii (A4_cmpbgtui IntRegs:$src1, (UDEC1 imm:$src2)), 0, 1)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002023
2024class Loada_pat<PatFrag Load, ValueType VT, PatFrag Addr, InstHexagon MI>
2025 : Pat<(VT (Load Addr:$addr)), (MI Addr:$addr)>;
2026
2027class Loadam_pat<PatFrag Load, ValueType VT, PatFrag Addr, PatFrag ValueMod,
2028 InstHexagon MI>
2029 : Pat<(VT (Load Addr:$addr)), (ValueMod (MI Addr:$addr))>;
2030
2031class Storea_pat<PatFrag Store, PatFrag Value, PatFrag Addr, InstHexagon MI>
2032 : Pat<(Store Value:$val, Addr:$addr), (MI Addr:$addr, Value:$val)>;
2033
2034class Stoream_pat<PatFrag Store, PatFrag Value, PatFrag Addr, PatFrag ValueMod,
2035 InstHexagon MI>
2036 : Pat<(Store Value:$val, Addr:$addr),
2037 (MI Addr:$addr, (ValueMod Value:$val))>;
2038
2039let AddedComplexity = 30 in {
2040 def: Storea_pat<truncstorei8, I32, addrga, PS_storerbabs>;
2041 def: Storea_pat<truncstorei16, I32, addrga, PS_storerhabs>;
2042 def: Storea_pat<store, I32, addrga, PS_storeriabs>;
2043 def: Storea_pat<store, I64, addrga, PS_storerdabs>;
2044
2045 def: Stoream_pat<truncstorei8, I64, addrga, LoReg, PS_storerbabs>;
2046 def: Stoream_pat<truncstorei16, I64, addrga, LoReg, PS_storerhabs>;
2047 def: Stoream_pat<truncstorei32, I64, addrga, LoReg, PS_storeriabs>;
2048}
2049
2050def: Storea_pat<SwapSt<atomic_store_8>, I32, addrgp, S2_storerbgp>;
2051def: Storea_pat<SwapSt<atomic_store_16>, I32, addrgp, S2_storerhgp>;
2052def: Storea_pat<SwapSt<atomic_store_32>, I32, addrgp, S2_storerigp>;
2053def: Storea_pat<SwapSt<atomic_store_64>, I64, addrgp, S2_storerdgp>;
2054
2055let AddedComplexity = 100 in {
2056 def: Storea_pat<truncstorei8, I32, addrgp, S2_storerbgp>;
2057 def: Storea_pat<truncstorei16, I32, addrgp, S2_storerhgp>;
2058 def: Storea_pat<store, I32, addrgp, S2_storerigp>;
2059 def: Storea_pat<store, I64, addrgp, S2_storerdgp>;
2060
2061 // Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
2062 // to "r0 = 1; memw(#foo) = r0"
2063 let AddedComplexity = 100 in
2064 def: Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
2065 (S2_storerbgp tglobaladdr:$global, (A2_tfrsi 1))>;
2066}
2067
2068class LoadAbs_pats <PatFrag ldOp, InstHexagon MI, ValueType VT = i32>
2069 : Pat <(VT (ldOp (HexagonCONST32 tglobaladdr:$absaddr))),
2070 (VT (MI tglobaladdr:$absaddr))>;
2071
2072let AddedComplexity = 30 in {
2073 def: LoadAbs_pats <load, PS_loadriabs>;
2074 def: LoadAbs_pats <zextloadi1, PS_loadrubabs>;
2075 def: LoadAbs_pats <sextloadi8, PS_loadrbabs>;
2076 def: LoadAbs_pats <extloadi8, PS_loadrubabs>;
2077 def: LoadAbs_pats <zextloadi8, PS_loadrubabs>;
2078 def: LoadAbs_pats <sextloadi16, PS_loadrhabs>;
2079 def: LoadAbs_pats <extloadi16, PS_loadruhabs>;
2080 def: LoadAbs_pats <zextloadi16, PS_loadruhabs>;
2081 def: LoadAbs_pats <load, PS_loadrdabs, i64>;
2082}
2083
2084let AddedComplexity = 30 in
2085def: Pat<(i64 (zextloadi1 (HexagonCONST32 tglobaladdr:$absaddr))),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00002086 (ToZext64 (PS_loadrubabs tglobaladdr:$absaddr))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002087
2088def: Loada_pat<atomic_load_8, i32, addrgp, L2_loadrubgp>;
2089def: Loada_pat<atomic_load_16, i32, addrgp, L2_loadruhgp>;
2090def: Loada_pat<atomic_load_32, i32, addrgp, L2_loadrigp>;
2091def: Loada_pat<atomic_load_64, i64, addrgp, L2_loadrdgp>;
2092
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002093def: Loadam_pat<load, i1, addrga, I32toI1, PS_loadrubabs>;
2094def: Loadam_pat<load, i1, addrgp, I32toI1, L2_loadrubgp>;
2095
2096def: Stoream_pat<store, I1, addrga, I1toI32, PS_storerbabs>;
2097def: Stoream_pat<store, I1, addrgp, I1toI32, S2_storerbgp>;
2098
2099// Map from load(globaladdress) -> mem[u][bhwd](#foo)
2100class LoadGP_pats <PatFrag ldOp, InstHexagon MI, ValueType VT = i32>
2101 : Pat <(VT (ldOp (HexagonCONST32_GP tglobaladdr:$global))),
2102 (VT (MI tglobaladdr:$global))>;
2103
2104let AddedComplexity = 100 in {
2105 def: LoadGP_pats <extloadi8, L2_loadrubgp>;
2106 def: LoadGP_pats <sextloadi8, L2_loadrbgp>;
2107 def: LoadGP_pats <zextloadi8, L2_loadrubgp>;
2108 def: LoadGP_pats <extloadi16, L2_loadruhgp>;
2109 def: LoadGP_pats <sextloadi16, L2_loadrhgp>;
2110 def: LoadGP_pats <zextloadi16, L2_loadruhgp>;
2111 def: LoadGP_pats <load, L2_loadrigp>;
2112 def: LoadGP_pats <load, L2_loadrdgp, i64>;
2113}
2114
2115// When the Interprocedural Global Variable optimizer realizes that a certain
2116// global variable takes only two constant values, it shrinks the global to
2117// a boolean. Catch those loads here in the following 3 patterns.
2118let AddedComplexity = 100 in {
2119 def: LoadGP_pats <extloadi1, L2_loadrubgp>;
2120 def: LoadGP_pats <zextloadi1, L2_loadrubgp>;
2121}
2122
2123// Transfer global address into a register
2124def: Pat<(HexagonCONST32 tglobaladdr:$Rs), (A2_tfrsi imm:$Rs)>;
2125def: Pat<(HexagonCONST32_GP tblockaddress:$Rs), (A2_tfrsi imm:$Rs)>;
2126def: Pat<(HexagonCONST32_GP tglobaladdr:$Rs), (A2_tfrsi imm:$Rs)>;
2127
2128let AddedComplexity = 30 in {
2129 def: Storea_pat<truncstorei8, I32, u32_0ImmPred, PS_storerbabs>;
2130 def: Storea_pat<truncstorei16, I32, u32_0ImmPred, PS_storerhabs>;
2131 def: Storea_pat<store, I32, u32_0ImmPred, PS_storeriabs>;
2132}
2133
2134let AddedComplexity = 30 in {
2135 def: Loada_pat<load, i32, u32_0ImmPred, PS_loadriabs>;
2136 def: Loada_pat<sextloadi8, i32, u32_0ImmPred, PS_loadrbabs>;
2137 def: Loada_pat<zextloadi8, i32, u32_0ImmPred, PS_loadrubabs>;
2138 def: Loada_pat<sextloadi16, i32, u32_0ImmPred, PS_loadrhabs>;
2139 def: Loada_pat<zextloadi16, i32, u32_0ImmPred, PS_loadruhabs>;
2140}
2141
2142// Indexed store word - global address.
2143// memw(Rs+#u6:2)=#S8
2144let AddedComplexity = 100 in
2145defm: Storex_add_pat<store, addrga, u6_2ImmPred, S4_storeiri_io>;
2146
2147// Load from a global address that has only one use in the current basic block.
2148let AddedComplexity = 100 in {
2149 def: Loada_pat<extloadi8, i32, addrga, PS_loadrubabs>;
2150 def: Loada_pat<sextloadi8, i32, addrga, PS_loadrbabs>;
2151 def: Loada_pat<zextloadi8, i32, addrga, PS_loadrubabs>;
2152
2153 def: Loada_pat<extloadi16, i32, addrga, PS_loadruhabs>;
2154 def: Loada_pat<sextloadi16, i32, addrga, PS_loadrhabs>;
2155 def: Loada_pat<zextloadi16, i32, addrga, PS_loadruhabs>;
2156
2157 def: Loada_pat<load, i32, addrga, PS_loadriabs>;
2158 def: Loada_pat<load, i64, addrga, PS_loadrdabs>;
2159}
2160
2161// Store to a global address that has only one use in the current basic block.
2162let AddedComplexity = 100 in {
2163 def: Storea_pat<truncstorei8, I32, addrga, PS_storerbabs>;
2164 def: Storea_pat<truncstorei16, I32, addrga, PS_storerhabs>;
2165 def: Storea_pat<store, I32, addrga, PS_storeriabs>;
2166 def: Storea_pat<store, I64, addrga, PS_storerdabs>;
2167
2168 def: Stoream_pat<truncstorei32, I64, addrga, LoReg, PS_storeriabs>;
2169}
2170
2171// i8/i16/i32 -> i64 loads
2172// We need a complexity of 120 here to override preceding handling of
2173// zextload.
2174let AddedComplexity = 120 in {
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00002175 def: Loadam_pat<extloadi8, i64, addrga, ToZext64, PS_loadrubabs>;
2176 def: Loadam_pat<sextloadi8, i64, addrga, ToSext64, PS_loadrbabs>;
2177 def: Loadam_pat<zextloadi8, i64, addrga, ToZext64, PS_loadrubabs>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002178
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00002179 def: Loadam_pat<extloadi16, i64, addrga, ToZext64, PS_loadruhabs>;
2180 def: Loadam_pat<sextloadi16, i64, addrga, ToSext64, PS_loadrhabs>;
2181 def: Loadam_pat<zextloadi16, i64, addrga, ToZext64, PS_loadruhabs>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002182
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00002183 def: Loadam_pat<extloadi32, i64, addrga, ToZext64, PS_loadriabs>;
2184 def: Loadam_pat<sextloadi32, i64, addrga, ToSext64, PS_loadriabs>;
2185 def: Loadam_pat<zextloadi32, i64, addrga, ToZext64, PS_loadriabs>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002186}
2187
2188let AddedComplexity = 100 in {
2189 def: Loada_pat<extloadi8, i32, addrgp, PS_loadrubabs>;
2190 def: Loada_pat<sextloadi8, i32, addrgp, PS_loadrbabs>;
2191 def: Loada_pat<zextloadi8, i32, addrgp, PS_loadrubabs>;
2192
2193 def: Loada_pat<extloadi16, i32, addrgp, PS_loadruhabs>;
2194 def: Loada_pat<sextloadi16, i32, addrgp, PS_loadrhabs>;
2195 def: Loada_pat<zextloadi16, i32, addrgp, PS_loadruhabs>;
2196
2197 def: Loada_pat<load, i32, addrgp, PS_loadriabs>;
2198 def: Loada_pat<load, i64, addrgp, PS_loadrdabs>;
2199}
2200
2201let AddedComplexity = 100 in {
2202 def: Storea_pat<truncstorei8, I32, addrgp, PS_storerbabs>;
2203 def: Storea_pat<truncstorei16, I32, addrgp, PS_storerhabs>;
2204 def: Storea_pat<store, I32, addrgp, PS_storeriabs>;
2205 def: Storea_pat<store, I64, addrgp, PS_storerdabs>;
2206}
2207
2208def: Loada_pat<atomic_load_8, i32, addrgp, PS_loadrubabs>;
2209def: Loada_pat<atomic_load_16, i32, addrgp, PS_loadruhabs>;
2210def: Loada_pat<atomic_load_32, i32, addrgp, PS_loadriabs>;
2211def: Loada_pat<atomic_load_64, i64, addrgp, PS_loadrdabs>;
2212
2213def: Storea_pat<SwapSt<atomic_store_8>, I32, addrgp, PS_storerbabs>;
2214def: Storea_pat<SwapSt<atomic_store_16>, I32, addrgp, PS_storerhabs>;
2215def: Storea_pat<SwapSt<atomic_store_32>, I32, addrgp, PS_storeriabs>;
2216def: Storea_pat<SwapSt<atomic_store_64>, I64, addrgp, PS_storerdabs>;
2217
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +00002218def: Pat<(or (or (or (shl (i64 (zext (and I32:$b, (i32 65535)))), (i32 16)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00002219 (i64 (zext (i32 (and I32:$a, (i32 65535)))))),
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +00002220 (shl (i64 (anyext (and I32:$c, (i32 65535)))), (i32 32))),
Krzysztof Parzyszek84755102016-11-06 17:56:48 +00002221 (shl (Aext64 I32:$d), (i32 48))),
Krzysztof Parzyszek601d7eb2016-11-09 14:16:29 +00002222 (A2_combinew (A2_combine_ll I32:$d, I32:$c),
2223 (A2_combine_ll I32:$b, I32:$a))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002224
2225// We need custom lowering of ISD::PREFETCH into HexagonISD::DCFETCH
2226// because the SDNode ISD::PREFETCH has properties MayLoad and MayStore.
2227// We don't really want either one here.
2228def SDTHexagonDCFETCH : SDTypeProfile<0, 2, [SDTCisPtrTy<0>,SDTCisInt<1>]>;
2229def HexagonDCFETCH : SDNode<"HexagonISD::DCFETCH", SDTHexagonDCFETCH,
2230 [SDNPHasChain]>;
2231
2232def: Pat<(HexagonDCFETCH IntRegs:$Rs, u11_3ImmPred:$u11_3),
2233 (Y2_dcfetchbo IntRegs:$Rs, imm:$u11_3)>;
2234def: Pat<(HexagonDCFETCH (i32 (add IntRegs:$Rs, u11_3ImmPred:$u11_3)), (i32 0)),
2235 (Y2_dcfetchbo IntRegs:$Rs, imm:$u11_3)>;
2236
2237def f32ImmPred : PatLeaf<(f32 fpimm:$F)>;
2238def f64ImmPred : PatLeaf<(f64 fpimm:$F)>;
2239
2240def ftoi : SDNodeXForm<fpimm, [{
2241 APInt I = N->getValueAPF().bitcastToAPInt();
2242 return CurDAG->getTargetConstant(I.getZExtValue(), SDLoc(N),
2243 MVT::getIntegerVT(I.getBitWidth()));
2244}]>;
2245
2246
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +00002247def: Pat<(sra (i64 (add (sra I64:$src1, u6_0ImmPred:$src2), 1)), (i32 1)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002248 (S2_asr_i_p_rnd I64:$src1, imm:$src2)>;
2249
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002250let AddedComplexity = 20 in {
2251 defm: Loadx_pat<load, f32, s30_2ImmPred, L2_loadri_io>;
2252 defm: Loadx_pat<load, f64, s29_3ImmPred, L2_loadrd_io>;
2253}
2254
2255let AddedComplexity = 60 in {
2256 defm : T_LoadAbsReg_Pat <load, L4_loadri_ur, f32>;
2257 defm : T_LoadAbsReg_Pat <load, L4_loadrd_ur, f64>;
2258}
2259
2260let AddedComplexity = 40 in {
2261 def: Loadxs_pat<load, f32, L4_loadri_rr>;
2262 def: Loadxs_pat<load, f64, L4_loadrd_rr>;
2263}
2264
2265let AddedComplexity = 20 in {
2266 def: Loadxs_simple_pat<load, f32, L4_loadri_rr>;
2267 def: Loadxs_simple_pat<load, f64, L4_loadrd_rr>;
2268}
2269
2270let AddedComplexity = 80 in {
2271 def: Loada_pat<load, f32, u32_0ImmPred, PS_loadriabs>;
2272 def: Loada_pat<load, f32, addrga, PS_loadriabs>;
2273 def: Loada_pat<load, f64, addrga, PS_loadrdabs>;
2274}
2275
2276let AddedComplexity = 100 in {
2277 def: LoadGP_pats <load, L2_loadrigp, f32>;
2278 def: LoadGP_pats <load, L2_loadrdgp, f64>;
2279}
2280
2281let AddedComplexity = 20 in {
2282 defm: Storex_pat<store, F32, s30_2ImmPred, S2_storeri_io>;
2283 defm: Storex_pat<store, F64, s29_3ImmPred, S2_storerd_io>;
2284}
2285
2286// Simple patterns should be tried with the least priority.
2287def: Storex_simple_pat<store, F32, S2_storeri_io>;
2288def: Storex_simple_pat<store, F64, S2_storerd_io>;
2289
2290let AddedComplexity = 60 in {
2291 defm : T_StoreAbsReg_Pats <S4_storeri_ur, IntRegs, f32, store>;
2292 defm : T_StoreAbsReg_Pats <S4_storerd_ur, DoubleRegs, f64, store>;
2293}
2294
2295let AddedComplexity = 40 in {
2296 def: Storexs_pat<store, F32, S4_storeri_rr>;
2297 def: Storexs_pat<store, F64, S4_storerd_rr>;
2298}
2299
2300let AddedComplexity = 20 in {
2301 def: Store_rr_pat<store, F32, S4_storeri_rr>;
2302 def: Store_rr_pat<store, F64, S4_storerd_rr>;
2303}
2304
2305let AddedComplexity = 80 in {
2306 def: Storea_pat<store, F32, addrga, PS_storeriabs>;
2307 def: Storea_pat<store, F64, addrga, PS_storerdabs>;
2308}
2309
2310let AddedComplexity = 100 in {
2311 def: Storea_pat<store, F32, addrgp, S2_storerigp>;
2312 def: Storea_pat<store, F64, addrgp, S2_storerdgp>;
2313}
2314
2315defm: Storex_pat<store, F32, s30_2ImmPred, S2_storeri_io>;
2316defm: Storex_pat<store, F64, s29_3ImmPred, S2_storerd_io>;
2317def: Storex_simple_pat<store, F32, S2_storeri_io>;
2318def: Storex_simple_pat<store, F64, S2_storerd_io>;
2319
2320def: Pat<(fadd F32:$src1, F32:$src2),
2321 (F2_sfadd F32:$src1, F32:$src2)>;
2322
2323def: Pat<(fsub F32:$src1, F32:$src2),
2324 (F2_sfsub F32:$src1, F32:$src2)>;
2325
2326def: Pat<(fmul F32:$src1, F32:$src2),
2327 (F2_sfmpy F32:$src1, F32:$src2)>;
2328
2329let Predicates = [HasV5T] in {
2330 def: Pat<(f32 (fminnum F32:$Rs, F32:$Rt)), (F2_sfmin F32:$Rs, F32:$Rt)>;
2331 def: Pat<(f32 (fmaxnum F32:$Rs, F32:$Rt)), (F2_sfmax F32:$Rs, F32:$Rt)>;
2332}
2333
2334let AddedComplexity = 100, Predicates = [HasV5T] in {
2335 class SfSel12<PatFrag Cmp, InstHexagon MI>
2336 : Pat<(select (i1 (Cmp F32:$Rs, F32:$Rt)), F32:$Rs, F32:$Rt),
2337 (MI F32:$Rs, F32:$Rt)>;
2338 class SfSel21<PatFrag Cmp, InstHexagon MI>
2339 : Pat<(select (i1 (Cmp F32:$Rs, F32:$Rt)), F32:$Rt, F32:$Rs),
2340 (MI F32:$Rs, F32:$Rt)>;
2341
2342 def: SfSel12<setolt, F2_sfmin>;
2343 def: SfSel12<setole, F2_sfmin>;
2344 def: SfSel12<setogt, F2_sfmax>;
2345 def: SfSel12<setoge, F2_sfmax>;
2346 def: SfSel21<setolt, F2_sfmax>;
2347 def: SfSel21<setole, F2_sfmax>;
2348 def: SfSel21<setogt, F2_sfmin>;
2349 def: SfSel21<setoge, F2_sfmin>;
2350}
2351
2352class T_fcmp32_pat<PatFrag OpNode, InstHexagon MI>
2353 : Pat<(i1 (OpNode F32:$src1, F32:$src2)),
2354 (MI F32:$src1, F32:$src2)>;
2355class T_fcmp64_pat<PatFrag OpNode, InstHexagon MI>
2356 : Pat<(i1 (OpNode F64:$src1, F64:$src2)),
2357 (MI F64:$src1, F64:$src2)>;
2358
2359def: T_fcmp32_pat<setoge, F2_sfcmpge>;
2360def: T_fcmp32_pat<setuo, F2_sfcmpuo>;
2361def: T_fcmp32_pat<setoeq, F2_sfcmpeq>;
2362def: T_fcmp32_pat<setogt, F2_sfcmpgt>;
2363
2364def: T_fcmp64_pat<setoge, F2_dfcmpge>;
2365def: T_fcmp64_pat<setuo, F2_dfcmpuo>;
2366def: T_fcmp64_pat<setoeq, F2_dfcmpeq>;
2367def: T_fcmp64_pat<setogt, F2_dfcmpgt>;
2368
2369let Predicates = [HasV5T] in
2370multiclass T_fcmp_pats<PatFrag cmpOp, InstHexagon IntMI, InstHexagon DoubleMI> {
2371 // IntRegs
2372 def: Pat<(i1 (cmpOp F32:$src1, F32:$src2)),
2373 (IntMI F32:$src1, F32:$src2)>;
2374 // DoubleRegs
2375 def: Pat<(i1 (cmpOp F64:$src1, F64:$src2)),
2376 (DoubleMI F64:$src1, F64:$src2)>;
2377}
2378
2379defm : T_fcmp_pats <seteq, F2_sfcmpeq, F2_dfcmpeq>;
2380defm : T_fcmp_pats <setgt, F2_sfcmpgt, F2_dfcmpgt>;
2381defm : T_fcmp_pats <setge, F2_sfcmpge, F2_dfcmpge>;
2382
2383//===----------------------------------------------------------------------===//
2384// Multiclass to define 'Def Pats' for unordered gt, ge, eq operations.
2385//===----------------------------------------------------------------------===//
2386let Predicates = [HasV5T] in
2387multiclass unord_Pats <PatFrag cmpOp, InstHexagon IntMI, InstHexagon DoubleMI> {
2388 // IntRegs
2389 def: Pat<(i1 (cmpOp F32:$src1, F32:$src2)),
2390 (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
2391 (IntMI F32:$src1, F32:$src2))>;
2392
2393 // DoubleRegs
2394 def: Pat<(i1 (cmpOp F64:$src1, F64:$src2)),
2395 (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
2396 (DoubleMI F64:$src1, F64:$src2))>;
2397}
2398
2399defm : unord_Pats <setuge, F2_sfcmpge, F2_dfcmpge>;
2400defm : unord_Pats <setugt, F2_sfcmpgt, F2_dfcmpgt>;
2401defm : unord_Pats <setueq, F2_sfcmpeq, F2_dfcmpeq>;
2402
2403//===----------------------------------------------------------------------===//
2404// Multiclass to define 'Def Pats' for the following dags:
2405// seteq(setoeq(op1, op2), 0) -> not(setoeq(op1, op2))
2406// seteq(setoeq(op1, op2), 1) -> setoeq(op1, op2)
2407// setne(setoeq(op1, op2), 0) -> setoeq(op1, op2)
2408// setne(setoeq(op1, op2), 1) -> not(setoeq(op1, op2))
2409//===----------------------------------------------------------------------===//
2410let Predicates = [HasV5T] in
2411multiclass eq_ordgePats <PatFrag cmpOp, InstHexagon IntMI,
2412 InstHexagon DoubleMI> {
2413 // IntRegs
2414 def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
2415 (C2_not (IntMI F32:$src1, F32:$src2))>;
2416 def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
2417 (IntMI F32:$src1, F32:$src2)>;
2418 def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
2419 (IntMI F32:$src1, F32:$src2)>;
2420 def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
2421 (C2_not (IntMI F32:$src1, F32:$src2))>;
2422
2423 // DoubleRegs
2424 def : Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
2425 (C2_not (DoubleMI F64:$src1, F64:$src2))>;
2426 def : Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 1)),
2427 (DoubleMI F64:$src1, F64:$src2)>;
2428 def : Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
2429 (DoubleMI F64:$src1, F64:$src2)>;
2430 def : Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 1)),
2431 (C2_not (DoubleMI F64:$src1, F64:$src2))>;
2432}
2433
2434defm : eq_ordgePats<setoeq, F2_sfcmpeq, F2_dfcmpeq>;
2435defm : eq_ordgePats<setoge, F2_sfcmpge, F2_dfcmpge>;
2436defm : eq_ordgePats<setogt, F2_sfcmpgt, F2_dfcmpgt>;
2437
2438//===----------------------------------------------------------------------===//
2439// Multiclass to define 'Def Pats' for the following dags:
2440// seteq(setolt(op1, op2), 0) -> not(setogt(op2, op1))
2441// seteq(setolt(op1, op2), 1) -> setogt(op2, op1)
2442// setne(setolt(op1, op2), 0) -> setogt(op2, op1)
2443// setne(setolt(op1, op2), 1) -> not(setogt(op2, op1))
2444//===----------------------------------------------------------------------===//
2445let Predicates = [HasV5T] in
2446multiclass eq_ordltPats <PatFrag cmpOp, InstHexagon IntMI,
2447 InstHexagon DoubleMI> {
2448 // IntRegs
2449 def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
2450 (C2_not (IntMI F32:$src2, F32:$src1))>;
2451 def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
2452 (IntMI F32:$src2, F32:$src1)>;
2453 def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
2454 (IntMI F32:$src2, F32:$src1)>;
2455 def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
2456 (C2_not (IntMI F32:$src2, F32:$src1))>;
2457
2458 // DoubleRegs
2459 def: Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
2460 (C2_not (DoubleMI F64:$src2, F64:$src1))>;
2461 def: Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 1)),
2462 (DoubleMI F64:$src2, F64:$src1)>;
2463 def: Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
2464 (DoubleMI F64:$src2, F64:$src1)>;
2465 def: Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
2466 (C2_not (DoubleMI F64:$src2, F64:$src1))>;
2467}
2468
2469defm : eq_ordltPats<setole, F2_sfcmpge, F2_dfcmpge>;
2470defm : eq_ordltPats<setolt, F2_sfcmpgt, F2_dfcmpgt>;
2471
2472
2473// o. seto inverse of setuo. http://llvm.org/docs/LangRef.html#i_fcmp
2474let Predicates = [HasV5T] in {
2475 def: Pat<(i1 (seto F32:$src1, F32:$src2)),
2476 (C2_not (F2_sfcmpuo F32:$src2, F32:$src1))>;
2477 def: Pat<(i1 (seto F32:$src1, f32ImmPred:$src2)),
2478 (C2_not (F2_sfcmpuo (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>;
2479 def: Pat<(i1 (seto F64:$src1, F64:$src2)),
2480 (C2_not (F2_dfcmpuo F64:$src2, F64:$src1))>;
2481 def: Pat<(i1 (seto F64:$src1, f64ImmPred:$src2)),
2482 (C2_not (F2_dfcmpuo (CONST64 (ftoi $src2)), F64:$src1))>;
2483}
2484
2485// Ordered lt.
2486let Predicates = [HasV5T] in {
2487 def: Pat<(i1 (setolt F32:$src1, F32:$src2)),
2488 (F2_sfcmpgt F32:$src2, F32:$src1)>;
2489 def: Pat<(i1 (setolt F32:$src1, f32ImmPred:$src2)),
2490 (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>;
2491 def: Pat<(i1 (setolt F64:$src1, F64:$src2)),
2492 (F2_dfcmpgt F64:$src2, F64:$src1)>;
2493 def: Pat<(i1 (setolt F64:$src1, f64ImmPred:$src2)),
2494 (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1)>;
2495}
2496
2497// Unordered lt.
2498let Predicates = [HasV5T] in {
2499 def: Pat<(i1 (setult F32:$src1, F32:$src2)),
2500 (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
2501 (F2_sfcmpgt F32:$src2, F32:$src1))>;
2502 def: Pat<(i1 (setult F32:$src1, f32ImmPred:$src2)),
2503 (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))),
2504 (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>;
2505 def: Pat<(i1 (setult F64:$src1, F64:$src2)),
2506 (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
2507 (F2_dfcmpgt F64:$src2, F64:$src1))>;
2508 def: Pat<(i1 (setult F64:$src1, f64ImmPred:$src2)),
2509 (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))),
2510 (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1))>;
2511}
2512
2513// Ordered le.
2514let Predicates = [HasV5T] in {
2515 // rs <= rt -> rt >= rs.
2516 def: Pat<(i1 (setole F32:$src1, F32:$src2)),
2517 (F2_sfcmpge F32:$src2, F32:$src1)>;
2518 def: Pat<(i1 (setole F32:$src1, f32ImmPred:$src2)),
2519 (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>;
2520
2521 // Rss <= Rtt -> Rtt >= Rss.
2522 def: Pat<(i1 (setole F64:$src1, F64:$src2)),
2523 (F2_dfcmpge F64:$src2, F64:$src1)>;
2524 def: Pat<(i1 (setole F64:$src1, f64ImmPred:$src2)),
2525 (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1)>;
2526}
2527
2528// Unordered le.
2529let Predicates = [HasV5T] in {
2530// rs <= rt -> rt >= rs.
2531 def: Pat<(i1 (setule F32:$src1, F32:$src2)),
2532 (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
2533 (F2_sfcmpge F32:$src2, F32:$src1))>;
2534 def: Pat<(i1 (setule F32:$src1, f32ImmPred:$src2)),
2535 (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))),
2536 (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>;
2537 def: Pat<(i1 (setule F64:$src1, F64:$src2)),
2538 (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
2539 (F2_dfcmpge F64:$src2, F64:$src1))>;
2540 def: Pat<(i1 (setule F64:$src1, f64ImmPred:$src2)),
2541 (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))),
2542 (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1))>;
2543}
2544
2545// Ordered ne.
2546let Predicates = [HasV5T] in {
2547 def: Pat<(i1 (setone F32:$src1, F32:$src2)),
2548 (C2_not (F2_sfcmpeq F32:$src1, F32:$src2))>;
2549 def: Pat<(i1 (setone F64:$src1, F64:$src2)),
2550 (C2_not (F2_dfcmpeq F64:$src1, F64:$src2))>;
2551 def: Pat<(i1 (setone F32:$src1, f32ImmPred:$src2)),
2552 (C2_not (F2_sfcmpeq F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))))>;
2553 def: Pat<(i1 (setone F64:$src1, f64ImmPred:$src2)),
2554 (C2_not (F2_dfcmpeq F64:$src1, (CONST64 (ftoi $src2))))>;
2555}
2556
2557// Unordered ne.
2558let Predicates = [HasV5T] in {
2559 def: Pat<(i1 (setune F32:$src1, F32:$src2)),
2560 (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
2561 (C2_not (F2_sfcmpeq F32:$src1, F32:$src2)))>;
2562 def: Pat<(i1 (setune F64:$src1, F64:$src2)),
2563 (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
2564 (C2_not (F2_dfcmpeq F64:$src1, F64:$src2)))>;
2565 def: Pat<(i1 (setune F32:$src1, f32ImmPred:$src2)),
2566 (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))),
2567 (C2_not (F2_sfcmpeq F32:$src1,
2568 (f32 (A2_tfrsi (ftoi $src2))))))>;
2569 def: Pat<(i1 (setune F64:$src1, f64ImmPred:$src2)),
2570 (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))),
2571 (C2_not (F2_dfcmpeq F64:$src1,
2572 (CONST64 (ftoi $src2)))))>;
2573}
2574
2575// Besides set[o|u][comparions], we also need set[comparisons].
2576let Predicates = [HasV5T] in {
2577 // lt.
2578 def: Pat<(i1 (setlt F32:$src1, F32:$src2)),
2579 (F2_sfcmpgt F32:$src2, F32:$src1)>;
2580 def: Pat<(i1 (setlt F32:$src1, f32ImmPred:$src2)),
2581 (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>;
2582 def: Pat<(i1 (setlt F64:$src1, F64:$src2)),
2583 (F2_dfcmpgt F64:$src2, F64:$src1)>;
2584 def: Pat<(i1 (setlt F64:$src1, f64ImmPred:$src2)),
2585 (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1)>;
2586
2587 // le.
2588 // rs <= rt -> rt >= rs.
2589 def: Pat<(i1 (setle F32:$src1, F32:$src2)),
2590 (F2_sfcmpge F32:$src2, F32:$src1)>;
2591 def: Pat<(i1 (setle F32:$src1, f32ImmPred:$src2)),
2592 (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>;
2593
2594 // Rss <= Rtt -> Rtt >= Rss.
2595 def: Pat<(i1 (setle F64:$src1, F64:$src2)),
2596 (F2_dfcmpge F64:$src2, F64:$src1)>;
2597 def: Pat<(i1 (setle F64:$src1, f64ImmPred:$src2)),
2598 (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1)>;
2599
2600 // ne.
2601 def: Pat<(i1 (setne F32:$src1, F32:$src2)),
2602 (C2_not (F2_sfcmpeq F32:$src1, F32:$src2))>;
2603 def: Pat<(i1 (setne F64:$src1, F64:$src2)),
2604 (C2_not (F2_dfcmpeq F64:$src1, F64:$src2))>;
2605 def: Pat<(i1 (setne F32:$src1, f32ImmPred:$src2)),
2606 (C2_not (F2_sfcmpeq F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))))>;
2607 def: Pat<(i1 (setne F64:$src1, f64ImmPred:$src2)),
2608 (C2_not (F2_dfcmpeq F64:$src1, (CONST64 (ftoi $src2))))>;
2609}
2610
2611
2612def: Pat<(f64 (fpextend F32:$Rs)), (F2_conv_sf2df F32:$Rs)>;
2613def: Pat<(f32 (fpround F64:$Rs)), (F2_conv_df2sf F64:$Rs)>;
2614
2615def: Pat<(f32 (sint_to_fp I32:$Rs)), (F2_conv_w2sf I32:$Rs)>;
2616def: Pat<(f32 (sint_to_fp I64:$Rs)), (F2_conv_d2sf I64:$Rs)>;
2617def: Pat<(f64 (sint_to_fp I32:$Rs)), (F2_conv_w2df I32:$Rs)>;
2618def: Pat<(f64 (sint_to_fp I64:$Rs)), (F2_conv_d2df I64:$Rs)>;
2619
2620def: Pat<(f32 (uint_to_fp I32:$Rs)), (F2_conv_uw2sf I32:$Rs)>;
2621def: Pat<(f32 (uint_to_fp I64:$Rs)), (F2_conv_ud2sf I64:$Rs)>;
2622def: Pat<(f64 (uint_to_fp I32:$Rs)), (F2_conv_uw2df I32:$Rs)>;
2623def: Pat<(f64 (uint_to_fp I64:$Rs)), (F2_conv_ud2df I64:$Rs)>;
2624
2625def: Pat<(i32 (fp_to_sint F32:$Rs)), (F2_conv_sf2w_chop F32:$Rs)>;
2626def: Pat<(i32 (fp_to_sint F64:$Rs)), (F2_conv_df2w_chop F64:$Rs)>;
2627def: Pat<(i64 (fp_to_sint F32:$Rs)), (F2_conv_sf2d_chop F32:$Rs)>;
2628def: Pat<(i64 (fp_to_sint F64:$Rs)), (F2_conv_df2d_chop F64:$Rs)>;
2629
2630def: Pat<(i32 (fp_to_uint F32:$Rs)), (F2_conv_sf2uw_chop F32:$Rs)>;
2631def: Pat<(i32 (fp_to_uint F64:$Rs)), (F2_conv_df2uw_chop F64:$Rs)>;
2632def: Pat<(i64 (fp_to_uint F32:$Rs)), (F2_conv_sf2ud_chop F32:$Rs)>;
2633def: Pat<(i64 (fp_to_uint F64:$Rs)), (F2_conv_df2ud_chop F64:$Rs)>;
2634
2635// Bitcast is different than [fp|sint|uint]_to_[sint|uint|fp].
2636let Predicates = [HasV5T] in {
2637 def: Pat <(i32 (bitconvert F32:$src)), (I32:$src)>;
2638 def: Pat <(f32 (bitconvert I32:$src)), (F32:$src)>;
2639 def: Pat <(i64 (bitconvert F64:$src)), (I64:$src)>;
2640 def: Pat <(f64 (bitconvert I64:$src)), (F64:$src)>;
2641}
2642
2643def : Pat <(fma F32:$src2, F32:$src3, F32:$src1),
2644 (F2_sffma F32:$src1, F32:$src2, F32:$src3)>;
2645
2646def : Pat <(fma (fneg F32:$src2), F32:$src3, F32:$src1),
2647 (F2_sffms F32:$src1, F32:$src2, F32:$src3)>;
2648
2649def : Pat <(fma F32:$src2, (fneg F32:$src3), F32:$src1),
2650 (F2_sffms F32:$src1, F32:$src2, F32:$src3)>;
2651
2652def: Pat<(select I1:$Pu, F32:$Rs, f32ImmPred:$imm),
2653 (C2_muxir I1:$Pu, F32:$Rs, (ftoi $imm))>,
2654 Requires<[HasV5T]>;
2655
2656def: Pat<(select I1:$Pu, f32ImmPred:$imm, F32:$Rt),
2657 (C2_muxri I1:$Pu, (ftoi $imm), F32:$Rt)>,
2658 Requires<[HasV5T]>;
2659
2660def: Pat<(select I1:$src1, F32:$src2, F32:$src3),
2661 (C2_mux I1:$src1, F32:$src2, F32:$src3)>,
2662 Requires<[HasV5T]>;
2663
2664def: Pat<(select (i1 (setult F32:$src1, F32:$src2)), F32:$src3, F32:$src4),
2665 (C2_mux (F2_sfcmpgt F32:$src2, F32:$src1), F32:$src4, F32:$src3)>,
2666 Requires<[HasV5T]>;
2667
2668def: Pat<(select I1:$src1, F64:$src2, F64:$src3),
2669 (C2_vmux I1:$src1, F64:$src2, F64:$src3)>,
2670 Requires<[HasV5T]>;
2671
2672def: Pat<(select (i1 (setult F64:$src1, F64:$src2)), F64:$src3, F64:$src4),
2673 (C2_vmux (F2_dfcmpgt F64:$src2, F64:$src1), F64:$src3, F64:$src4)>,
2674 Requires<[HasV5T]>;
2675
2676// Map from p0 = pnot(p0); r0 = select(p0, #i, r1)
2677// => r0 = mux(p0, #i, r1)
2678def: Pat<(select (not I1:$src1), f32ImmPred:$src2, F32:$src3),
2679 (C2_muxir I1:$src1, F32:$src3, (ftoi $src2))>,
2680 Requires<[HasV5T]>;
2681
2682// Map from p0 = pnot(p0); r0 = mux(p0, r1, #i)
2683// => r0 = mux(p0, r1, #i)
2684def: Pat<(select (not I1:$src1), F32:$src2, f32ImmPred:$src3),
2685 (C2_muxri I1:$src1, (ftoi $src3), F32:$src2)>,
2686 Requires<[HasV5T]>;
2687
2688def: Pat<(i32 (fp_to_sint F64:$src1)),
2689 (LoReg (F2_conv_df2d_chop F64:$src1))>,
2690 Requires<[HasV5T]>;
2691
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00002692def : Pat <(fabs F32:$src1),
2693 (S2_clrbit_i F32:$src1, 31)>,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002694 Requires<[HasV5T]>;
2695
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00002696def : Pat <(fneg F32:$src1),
2697 (S2_togglebit_i F32:$src1, 31)>,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002698 Requires<[HasV5T]>;
2699
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +00002700def: Pat<(fabs F64:$Rs),
2701 (REG_SEQUENCE DoubleRegs,
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00002702 (S2_clrbit_i (HiReg $Rs), 31), isub_hi,
2703 (i32 (LoReg $Rs)), isub_lo)>;
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +00002704
2705def: Pat<(fneg F64:$Rs),
2706 (REG_SEQUENCE DoubleRegs,
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00002707 (S2_togglebit_i (HiReg $Rs), 31), isub_hi,
2708 (i32 (LoReg $Rs)), isub_lo)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002709
2710def alignedload : PatFrag<(ops node:$addr), (load $addr), [{
2711 return isAlignedMemNode(dyn_cast<MemSDNode>(N));
2712}]>;
2713
2714def unalignedload : PatFrag<(ops node:$addr), (load $addr), [{
2715 return !isAlignedMemNode(dyn_cast<MemSDNode>(N));
2716}]>;
2717
2718def alignedstore : PatFrag<(ops node:$val, node:$addr), (store $val, $addr), [{
2719 return isAlignedMemNode(dyn_cast<MemSDNode>(N));
2720}]>;
2721
2722def unalignedstore : PatFrag<(ops node:$val, node:$addr), (store $val, $addr), [{
2723 return !isAlignedMemNode(dyn_cast<MemSDNode>(N));
2724}]>;
2725
2726
2727multiclass vS32b_ai_pats <ValueType VTSgl, ValueType VTDbl> {
2728 // Aligned stores
2729 def : Pat<(alignedstore (VTSgl VectorRegs:$src1), IntRegs:$addr),
2730 (V6_vS32b_ai IntRegs:$addr, 0, (VTSgl VectorRegs:$src1))>,
2731 Requires<[UseHVXSgl]>;
2732 def : Pat<(unalignedstore (VTSgl VectorRegs:$src1), IntRegs:$addr),
2733 (V6_vS32Ub_ai IntRegs:$addr, 0, (VTSgl VectorRegs:$src1))>,
2734 Requires<[UseHVXSgl]>;
2735
2736 // 128B Aligned stores
2737 def : Pat<(alignedstore (VTDbl VectorRegs128B:$src1), IntRegs:$addr),
2738 (V6_vS32b_ai_128B IntRegs:$addr, 0, (VTDbl VectorRegs128B:$src1))>,
2739 Requires<[UseHVXDbl]>;
2740 def : Pat<(unalignedstore (VTDbl VectorRegs128B:$src1), IntRegs:$addr),
2741 (V6_vS32Ub_ai_128B IntRegs:$addr, 0, (VTDbl VectorRegs128B:$src1))>,
2742 Requires<[UseHVXDbl]>;
2743
2744 // Fold Add R+OFF into vector store.
2745 let AddedComplexity = 10 in {
2746 def : Pat<(alignedstore (VTSgl VectorRegs:$src1),
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +00002747 (add IntRegs:$src2, Iss4_6:$offset)),
2748 (V6_vS32b_ai IntRegs:$src2, Iss4_6:$offset,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002749 (VTSgl VectorRegs:$src1))>,
2750 Requires<[UseHVXSgl]>;
2751 def : Pat<(unalignedstore (VTSgl VectorRegs:$src1),
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +00002752 (add IntRegs:$src2, Iss4_6:$offset)),
2753 (V6_vS32Ub_ai IntRegs:$src2, Iss4_6:$offset,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002754 (VTSgl VectorRegs:$src1))>,
2755 Requires<[UseHVXSgl]>;
2756
2757 // Fold Add R+OFF into vector store 128B.
2758 def : Pat<(alignedstore (VTDbl VectorRegs128B:$src1),
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +00002759 (add IntRegs:$src2, Iss4_7:$offset)),
2760 (V6_vS32b_ai_128B IntRegs:$src2, Iss4_7:$offset,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002761 (VTDbl VectorRegs128B:$src1))>,
2762 Requires<[UseHVXDbl]>;
2763 def : Pat<(unalignedstore (VTDbl VectorRegs128B:$src1),
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +00002764 (add IntRegs:$src2, Iss4_7:$offset)),
2765 (V6_vS32Ub_ai_128B IntRegs:$src2, Iss4_7:$offset,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002766 (VTDbl VectorRegs128B:$src1))>,
2767 Requires<[UseHVXDbl]>;
2768 }
2769}
2770
2771defm : vS32b_ai_pats <v64i8, v128i8>;
2772defm : vS32b_ai_pats <v32i16, v64i16>;
2773defm : vS32b_ai_pats <v16i32, v32i32>;
2774defm : vS32b_ai_pats <v8i64, v16i64>;
2775
2776
2777multiclass vL32b_ai_pats <ValueType VTSgl, ValueType VTDbl> {
2778 // Aligned loads
2779 def : Pat < (VTSgl (alignedload IntRegs:$addr)),
2780 (V6_vL32b_ai IntRegs:$addr, 0) >,
2781 Requires<[UseHVXSgl]>;
2782 def : Pat < (VTSgl (unalignedload IntRegs:$addr)),
2783 (V6_vL32Ub_ai IntRegs:$addr, 0) >,
2784 Requires<[UseHVXSgl]>;
2785
2786 // 128B Load
2787 def : Pat < (VTDbl (alignedload IntRegs:$addr)),
2788 (V6_vL32b_ai_128B IntRegs:$addr, 0) >,
2789 Requires<[UseHVXDbl]>;
2790 def : Pat < (VTDbl (unalignedload IntRegs:$addr)),
2791 (V6_vL32Ub_ai_128B IntRegs:$addr, 0) >,
2792 Requires<[UseHVXDbl]>;
2793
2794 // Fold Add R+OFF into vector load.
2795 let AddedComplexity = 10 in {
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +00002796 def : Pat<(VTDbl (alignedload (add IntRegs:$src2, Iss4_7:$offset))),
2797 (V6_vL32b_ai_128B IntRegs:$src2, Iss4_7:$offset)>,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002798 Requires<[UseHVXDbl]>;
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +00002799 def : Pat<(VTDbl (unalignedload (add IntRegs:$src2, Iss4_7:$offset))),
2800 (V6_vL32Ub_ai_128B IntRegs:$src2, Iss4_7:$offset)>,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002801 Requires<[UseHVXDbl]>;
2802
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +00002803 def : Pat<(VTSgl (alignedload (add IntRegs:$src2, Iss4_6:$offset))),
2804 (V6_vL32b_ai IntRegs:$src2, Iss4_6:$offset)>,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002805 Requires<[UseHVXSgl]>;
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +00002806 def : Pat<(VTSgl (unalignedload (add IntRegs:$src2, Iss4_6:$offset))),
2807 (V6_vL32Ub_ai IntRegs:$src2, Iss4_6:$offset)>,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002808 Requires<[UseHVXSgl]>;
2809 }
2810}
2811
2812defm : vL32b_ai_pats <v64i8, v128i8>;
2813defm : vL32b_ai_pats <v32i16, v64i16>;
2814defm : vL32b_ai_pats <v16i32, v32i32>;
2815defm : vL32b_ai_pats <v8i64, v16i64>;
2816
2817multiclass STrivv_pats <ValueType VTSgl, ValueType VTDbl> {
2818 def : Pat<(alignedstore (VTSgl VecDblRegs:$src1), IntRegs:$addr),
2819 (PS_vstorerw_ai IntRegs:$addr, 0, (VTSgl VecDblRegs:$src1))>,
2820 Requires<[UseHVXSgl]>;
2821 def : Pat<(unalignedstore (VTSgl VecDblRegs:$src1), IntRegs:$addr),
2822 (PS_vstorerwu_ai IntRegs:$addr, 0, (VTSgl VecDblRegs:$src1))>,
2823 Requires<[UseHVXSgl]>;
2824
2825 def : Pat<(alignedstore (VTDbl VecDblRegs128B:$src1), IntRegs:$addr),
2826 (PS_vstorerw_ai_128B IntRegs:$addr, 0,
2827 (VTDbl VecDblRegs128B:$src1))>,
2828 Requires<[UseHVXDbl]>;
2829 def : Pat<(unalignedstore (VTDbl VecDblRegs128B:$src1), IntRegs:$addr),
2830 (PS_vstorerwu_ai_128B IntRegs:$addr, 0,
2831 (VTDbl VecDblRegs128B:$src1))>,
2832 Requires<[UseHVXDbl]>;
2833}
2834
2835defm : STrivv_pats <v128i8, v256i8>;
2836defm : STrivv_pats <v64i16, v128i16>;
2837defm : STrivv_pats <v32i32, v64i32>;
2838defm : STrivv_pats <v16i64, v32i64>;
2839
2840multiclass LDrivv_pats <ValueType VTSgl, ValueType VTDbl> {
2841 def : Pat<(VTSgl (alignedload I32:$addr)),
2842 (PS_vloadrw_ai I32:$addr, 0)>,
2843 Requires<[UseHVXSgl]>;
2844 def : Pat<(VTSgl (unalignedload I32:$addr)),
2845 (PS_vloadrwu_ai I32:$addr, 0)>,
2846 Requires<[UseHVXSgl]>;
2847
2848 def : Pat<(VTDbl (alignedload I32:$addr)),
2849 (PS_vloadrw_ai_128B I32:$addr, 0)>,
2850 Requires<[UseHVXDbl]>;
2851 def : Pat<(VTDbl (unalignedload I32:$addr)),
2852 (PS_vloadrwu_ai_128B I32:$addr, 0)>,
2853 Requires<[UseHVXDbl]>;
2854}
2855
2856defm : LDrivv_pats <v128i8, v256i8>;
2857defm : LDrivv_pats <v64i16, v128i16>;
2858defm : LDrivv_pats <v32i32, v64i32>;
2859defm : LDrivv_pats <v16i64, v32i64>;
2860
2861let Predicates = [HasV60T,UseHVXSgl] in {
2862 def: Pat<(select I1:$Pu, (v16i32 VectorRegs:$Vs), VectorRegs:$Vt),
2863 (PS_vselect I1:$Pu, VectorRegs:$Vs, VectorRegs:$Vt)>;
2864 def: Pat<(select I1:$Pu, (v32i32 VecDblRegs:$Vs), VecDblRegs:$Vt),
2865 (PS_wselect I1:$Pu, VecDblRegs:$Vs, VecDblRegs:$Vt)>;
2866}
2867let Predicates = [HasV60T,UseHVXDbl] in {
2868 def: Pat<(select I1:$Pu, (v32i32 VectorRegs128B:$Vs), VectorRegs128B:$Vt),
2869 (PS_vselect_128B I1:$Pu, VectorRegs128B:$Vs, VectorRegs128B:$Vt)>;
2870 def: Pat<(select I1:$Pu, (v64i32 VecDblRegs128B:$Vs), VecDblRegs128B:$Vt),
2871 (PS_wselect_128B I1:$Pu, VecDblRegs128B:$Vs, VecDblRegs128B:$Vt)>;
2872}
2873
2874
2875def SDTHexagonVCOMBINE: SDTypeProfile<1, 2, [SDTCisSameAs<1, 2>,
2876 SDTCisSubVecOfVec<1, 0>]>;
2877
2878def HexagonVCOMBINE: SDNode<"HexagonISD::VCOMBINE", SDTHexagonVCOMBINE>;
2879
2880def: Pat<(v32i32 (HexagonVCOMBINE (v16i32 VectorRegs:$Vs),
2881 (v16i32 VectorRegs:$Vt))),
2882 (V6_vcombine VectorRegs:$Vs, VectorRegs:$Vt)>,
2883 Requires<[UseHVXSgl]>;
2884def: Pat<(v64i32 (HexagonVCOMBINE (v32i32 VecDblRegs:$Vs),
2885 (v32i32 VecDblRegs:$Vt))),
2886 (V6_vcombine_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
2887 Requires<[UseHVXDbl]>;
2888
2889def SDTHexagonVPACK: SDTypeProfile<1, 3, [SDTCisSameAs<1, 2>,
2890 SDTCisInt<3>]>;
2891
2892def HexagonVPACK: SDNode<"HexagonISD::VPACK", SDTHexagonVPACK>;
2893
2894// 0 as the last argument denotes vpacke. 1 denotes vpacko
2895def: Pat<(v64i8 (HexagonVPACK (v64i8 VectorRegs:$Vs),
2896 (v64i8 VectorRegs:$Vt), (i32 0))),
2897 (V6_vpackeb VectorRegs:$Vs, VectorRegs:$Vt)>,
2898 Requires<[UseHVXSgl]>;
2899def: Pat<(v64i8 (HexagonVPACK (v64i8 VectorRegs:$Vs),
2900 (v64i8 VectorRegs:$Vt), (i32 1))),
2901 (V6_vpackob VectorRegs:$Vs, VectorRegs:$Vt)>,
2902 Requires<[UseHVXSgl]>;
2903def: Pat<(v32i16 (HexagonVPACK (v32i16 VectorRegs:$Vs),
2904 (v32i16 VectorRegs:$Vt), (i32 0))),
2905 (V6_vpackeh VectorRegs:$Vs, VectorRegs:$Vt)>,
2906 Requires<[UseHVXSgl]>;
2907def: Pat<(v32i16 (HexagonVPACK (v32i16 VectorRegs:$Vs),
2908 (v32i16 VectorRegs:$Vt), (i32 1))),
2909 (V6_vpackoh VectorRegs:$Vs, VectorRegs:$Vt)>,
2910 Requires<[UseHVXSgl]>;
2911
2912def: Pat<(v128i8 (HexagonVPACK (v128i8 VecDblRegs:$Vs),
2913 (v128i8 VecDblRegs:$Vt), (i32 0))),
2914 (V6_vpackeb_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
2915 Requires<[UseHVXDbl]>;
2916def: Pat<(v128i8 (HexagonVPACK (v128i8 VecDblRegs:$Vs),
2917 (v128i8 VecDblRegs:$Vt), (i32 1))),
2918 (V6_vpackob_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
2919 Requires<[UseHVXDbl]>;
2920def: Pat<(v64i16 (HexagonVPACK (v64i16 VecDblRegs:$Vs),
2921 (v64i16 VecDblRegs:$Vt), (i32 0))),
2922 (V6_vpackeh_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
2923 Requires<[UseHVXDbl]>;
2924def: Pat<(v64i16 (HexagonVPACK (v64i16 VecDblRegs:$Vs),
2925 (v64i16 VecDblRegs:$Vt), (i32 1))),
2926 (V6_vpackoh_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
2927 Requires<[UseHVXDbl]>;
2928
2929def V2I1: PatLeaf<(v2i1 PredRegs:$R)>;
2930def V4I1: PatLeaf<(v4i1 PredRegs:$R)>;
2931def V8I1: PatLeaf<(v8i1 PredRegs:$R)>;
2932def V4I8: PatLeaf<(v4i8 IntRegs:$R)>;
2933def V2I16: PatLeaf<(v2i16 IntRegs:$R)>;
2934def V8I8: PatLeaf<(v8i8 DoubleRegs:$R)>;
2935def V4I16: PatLeaf<(v4i16 DoubleRegs:$R)>;
2936def V2I32: PatLeaf<(v2i32 DoubleRegs:$R)>;
2937
2938
2939multiclass bitconvert_32<ValueType a, ValueType b> {
2940 def : Pat <(b (bitconvert (a IntRegs:$src))),
2941 (b IntRegs:$src)>;
2942 def : Pat <(a (bitconvert (b IntRegs:$src))),
2943 (a IntRegs:$src)>;
2944}
2945
2946multiclass bitconvert_64<ValueType a, ValueType b> {
2947 def : Pat <(b (bitconvert (a DoubleRegs:$src))),
2948 (b DoubleRegs:$src)>;
2949 def : Pat <(a (bitconvert (b DoubleRegs:$src))),
2950 (a DoubleRegs:$src)>;
2951}
2952
2953// Bit convert vector types to integers.
2954defm : bitconvert_32<v4i8, i32>;
2955defm : bitconvert_32<v2i16, i32>;
2956defm : bitconvert_64<v8i8, i64>;
2957defm : bitconvert_64<v4i16, i64>;
2958defm : bitconvert_64<v2i32, i64>;
2959
2960def: Pat<(sra (v4i16 DoubleRegs:$src1), u4_0ImmPred:$src2),
2961 (S2_asr_i_vh DoubleRegs:$src1, imm:$src2)>;
2962def: Pat<(srl (v4i16 DoubleRegs:$src1), u4_0ImmPred:$src2),
2963 (S2_lsr_i_vh DoubleRegs:$src1, imm:$src2)>;
2964def: Pat<(shl (v4i16 DoubleRegs:$src1), u4_0ImmPred:$src2),
2965 (S2_asl_i_vh DoubleRegs:$src1, imm:$src2)>;
2966
2967def: Pat<(sra (v2i32 DoubleRegs:$src1), u5_0ImmPred:$src2),
2968 (S2_asr_i_vw DoubleRegs:$src1, imm:$src2)>;
2969def: Pat<(srl (v2i32 DoubleRegs:$src1), u5_0ImmPred:$src2),
2970 (S2_lsr_i_vw DoubleRegs:$src1, imm:$src2)>;
2971def: Pat<(shl (v2i32 DoubleRegs:$src1), u5_0ImmPred:$src2),
2972 (S2_asl_i_vw DoubleRegs:$src1, imm:$src2)>;
2973
2974def : Pat<(v2i16 (add (v2i16 IntRegs:$src1), (v2i16 IntRegs:$src2))),
2975 (A2_svaddh IntRegs:$src1, IntRegs:$src2)>;
2976
2977def : Pat<(v2i16 (sub (v2i16 IntRegs:$src1), (v2i16 IntRegs:$src2))),
2978 (A2_svsubh IntRegs:$src1, IntRegs:$src2)>;
2979
2980def HexagonVSPLATB: SDNode<"HexagonISD::VSPLATB", SDTUnaryOp>;
2981def HexagonVSPLATH: SDNode<"HexagonISD::VSPLATH", SDTUnaryOp>;
2982
2983// Replicate the low 8-bits from 32-bits input register into each of the
2984// four bytes of 32-bits destination register.
2985def: Pat<(v4i8 (HexagonVSPLATB I32:$Rs)), (S2_vsplatrb I32:$Rs)>;
2986
2987// Replicate the low 16-bits from 32-bits input register into each of the
2988// four halfwords of 64-bits destination register.
2989def: Pat<(v4i16 (HexagonVSPLATH I32:$Rs)), (S2_vsplatrh I32:$Rs)>;
2990
2991
2992class VArith_pat <InstHexagon MI, SDNode Op, PatFrag Type>
2993 : Pat <(Op Type:$Rss, Type:$Rtt),
2994 (MI Type:$Rss, Type:$Rtt)>;
2995
2996def: VArith_pat <A2_vaddub, add, V8I8>;
2997def: VArith_pat <A2_vaddh, add, V4I16>;
2998def: VArith_pat <A2_vaddw, add, V2I32>;
2999def: VArith_pat <A2_vsubub, sub, V8I8>;
3000def: VArith_pat <A2_vsubh, sub, V4I16>;
3001def: VArith_pat <A2_vsubw, sub, V2I32>;
3002
3003def: VArith_pat <A2_and, and, V2I16>;
3004def: VArith_pat <A2_xor, xor, V2I16>;
3005def: VArith_pat <A2_or, or, V2I16>;
3006
3007def: VArith_pat <A2_andp, and, V8I8>;
3008def: VArith_pat <A2_andp, and, V4I16>;
3009def: VArith_pat <A2_andp, and, V2I32>;
3010def: VArith_pat <A2_orp, or, V8I8>;
3011def: VArith_pat <A2_orp, or, V4I16>;
3012def: VArith_pat <A2_orp, or, V2I32>;
3013def: VArith_pat <A2_xorp, xor, V8I8>;
3014def: VArith_pat <A2_xorp, xor, V4I16>;
3015def: VArith_pat <A2_xorp, xor, V2I32>;
3016
3017def: Pat<(v2i32 (sra V2I32:$b, (i64 (HexagonCOMBINE (i32 u5_0ImmPred:$c),
3018 (i32 u5_0ImmPred:$c))))),
3019 (S2_asr_i_vw V2I32:$b, imm:$c)>;
3020def: Pat<(v2i32 (srl V2I32:$b, (i64 (HexagonCOMBINE (i32 u5_0ImmPred:$c),
3021 (i32 u5_0ImmPred:$c))))),
3022 (S2_lsr_i_vw V2I32:$b, imm:$c)>;
3023def: Pat<(v2i32 (shl V2I32:$b, (i64 (HexagonCOMBINE (i32 u5_0ImmPred:$c),
3024 (i32 u5_0ImmPred:$c))))),
3025 (S2_asl_i_vw V2I32:$b, imm:$c)>;
3026
3027def: Pat<(v4i16 (sra V4I16:$b, (v4i16 (HexagonVSPLATH (i32 (u4_0ImmPred:$c)))))),
3028 (S2_asr_i_vh V4I16:$b, imm:$c)>;
3029def: Pat<(v4i16 (srl V4I16:$b, (v4i16 (HexagonVSPLATH (i32 (u4_0ImmPred:$c)))))),
3030 (S2_lsr_i_vh V4I16:$b, imm:$c)>;
3031def: Pat<(v4i16 (shl V4I16:$b, (v4i16 (HexagonVSPLATH (i32 (u4_0ImmPred:$c)))))),
3032 (S2_asl_i_vh V4I16:$b, imm:$c)>;
3033
3034
3035def SDTHexagon_v2i32_v2i32_i32 : SDTypeProfile<1, 2,
3036 [SDTCisSameAs<0, 1>, SDTCisVT<0, v2i32>, SDTCisInt<2>]>;
3037def SDTHexagon_v4i16_v4i16_i32 : SDTypeProfile<1, 2,
3038 [SDTCisSameAs<0, 1>, SDTCisVT<0, v4i16>, SDTCisInt<2>]>;
3039
3040def HexagonVSRAW: SDNode<"HexagonISD::VSRAW", SDTHexagon_v2i32_v2i32_i32>;
3041def HexagonVSRAH: SDNode<"HexagonISD::VSRAH", SDTHexagon_v4i16_v4i16_i32>;
3042def HexagonVSRLW: SDNode<"HexagonISD::VSRLW", SDTHexagon_v2i32_v2i32_i32>;
3043def HexagonVSRLH: SDNode<"HexagonISD::VSRLH", SDTHexagon_v4i16_v4i16_i32>;
3044def HexagonVSHLW: SDNode<"HexagonISD::VSHLW", SDTHexagon_v2i32_v2i32_i32>;
3045def HexagonVSHLH: SDNode<"HexagonISD::VSHLH", SDTHexagon_v4i16_v4i16_i32>;
3046
3047def: Pat<(v2i32 (HexagonVSRAW V2I32:$Rs, u5_0ImmPred:$u5)),
3048 (S2_asr_i_vw V2I32:$Rs, imm:$u5)>;
3049def: Pat<(v4i16 (HexagonVSRAH V4I16:$Rs, u4_0ImmPred:$u4)),
3050 (S2_asr_i_vh V4I16:$Rs, imm:$u4)>;
3051def: Pat<(v2i32 (HexagonVSRLW V2I32:$Rs, u5_0ImmPred:$u5)),
3052 (S2_lsr_i_vw V2I32:$Rs, imm:$u5)>;
3053def: Pat<(v4i16 (HexagonVSRLH V4I16:$Rs, u4_0ImmPred:$u4)),
3054 (S2_lsr_i_vh V4I16:$Rs, imm:$u4)>;
3055def: Pat<(v2i32 (HexagonVSHLW V2I32:$Rs, u5_0ImmPred:$u5)),
3056 (S2_asl_i_vw V2I32:$Rs, imm:$u5)>;
3057def: Pat<(v4i16 (HexagonVSHLH V4I16:$Rs, u4_0ImmPred:$u4)),
3058 (S2_asl_i_vh V4I16:$Rs, imm:$u4)>;
3059
3060class vshift_rr_pat<InstHexagon MI, SDNode Op, PatFrag Value>
3061 : Pat <(Op Value:$Rs, I32:$Rt),
3062 (MI Value:$Rs, I32:$Rt)>;
3063
3064def: vshift_rr_pat <S2_asr_r_vw, HexagonVSRAW, V2I32>;
3065def: vshift_rr_pat <S2_asr_r_vh, HexagonVSRAH, V4I16>;
3066def: vshift_rr_pat <S2_lsr_r_vw, HexagonVSRLW, V2I32>;
3067def: vshift_rr_pat <S2_lsr_r_vh, HexagonVSRLH, V4I16>;
3068def: vshift_rr_pat <S2_asl_r_vw, HexagonVSHLW, V2I32>;
3069def: vshift_rr_pat <S2_asl_r_vh, HexagonVSHLH, V4I16>;
3070
3071
3072def SDTHexagonVecCompare_v8i8 : SDTypeProfile<1, 2,
3073 [SDTCisSameAs<1, 2>, SDTCisVT<0, i1>, SDTCisVT<1, v8i8>]>;
3074def SDTHexagonVecCompare_v4i16 : SDTypeProfile<1, 2,
3075 [SDTCisSameAs<1, 2>, SDTCisVT<0, i1>, SDTCisVT<1, v4i16>]>;
3076def SDTHexagonVecCompare_v2i32 : SDTypeProfile<1, 2,
3077 [SDTCisSameAs<1, 2>, SDTCisVT<0, i1>, SDTCisVT<1, v2i32>]>;
3078
3079def HexagonVCMPBEQ: SDNode<"HexagonISD::VCMPBEQ", SDTHexagonVecCompare_v8i8>;
3080def HexagonVCMPBGT: SDNode<"HexagonISD::VCMPBGT", SDTHexagonVecCompare_v8i8>;
3081def HexagonVCMPBGTU: SDNode<"HexagonISD::VCMPBGTU", SDTHexagonVecCompare_v8i8>;
3082def HexagonVCMPHEQ: SDNode<"HexagonISD::VCMPHEQ", SDTHexagonVecCompare_v4i16>;
3083def HexagonVCMPHGT: SDNode<"HexagonISD::VCMPHGT", SDTHexagonVecCompare_v4i16>;
3084def HexagonVCMPHGTU: SDNode<"HexagonISD::VCMPHGTU", SDTHexagonVecCompare_v4i16>;
3085def HexagonVCMPWEQ: SDNode<"HexagonISD::VCMPWEQ", SDTHexagonVecCompare_v2i32>;
3086def HexagonVCMPWGT: SDNode<"HexagonISD::VCMPWGT", SDTHexagonVecCompare_v2i32>;
3087def HexagonVCMPWGTU: SDNode<"HexagonISD::VCMPWGTU", SDTHexagonVecCompare_v2i32>;
3088
3089
3090class vcmp_i1_pat<InstHexagon MI, SDNode Op, PatFrag Value>
3091 : Pat <(i1 (Op Value:$Rs, Value:$Rt)),
3092 (MI Value:$Rs, Value:$Rt)>;
3093
3094def: vcmp_i1_pat<A2_vcmpbeq, HexagonVCMPBEQ, V8I8>;
3095def: vcmp_i1_pat<A4_vcmpbgt, HexagonVCMPBGT, V8I8>;
3096def: vcmp_i1_pat<A2_vcmpbgtu, HexagonVCMPBGTU, V8I8>;
3097
3098def: vcmp_i1_pat<A2_vcmpheq, HexagonVCMPHEQ, V4I16>;
3099def: vcmp_i1_pat<A2_vcmphgt, HexagonVCMPHGT, V4I16>;
3100def: vcmp_i1_pat<A2_vcmphgtu, HexagonVCMPHGTU, V4I16>;
3101
3102def: vcmp_i1_pat<A2_vcmpweq, HexagonVCMPWEQ, V2I32>;
3103def: vcmp_i1_pat<A2_vcmpwgt, HexagonVCMPWGT, V2I32>;
3104def: vcmp_i1_pat<A2_vcmpwgtu, HexagonVCMPWGTU, V2I32>;
3105
3106
3107class vcmp_vi1_pat<InstHexagon MI, PatFrag Op, PatFrag InVal, ValueType OutTy>
3108 : Pat <(OutTy (Op InVal:$Rs, InVal:$Rt)),
3109 (MI InVal:$Rs, InVal:$Rt)>;
3110
3111def: vcmp_vi1_pat<A2_vcmpweq, seteq, V2I32, v2i1>;
3112def: vcmp_vi1_pat<A2_vcmpwgt, setgt, V2I32, v2i1>;
3113def: vcmp_vi1_pat<A2_vcmpwgtu, setugt, V2I32, v2i1>;
3114
3115def: vcmp_vi1_pat<A2_vcmpheq, seteq, V4I16, v4i1>;
3116def: vcmp_vi1_pat<A2_vcmphgt, setgt, V4I16, v4i1>;
3117def: vcmp_vi1_pat<A2_vcmphgtu, setugt, V4I16, v4i1>;
3118
3119def: Pat<(mul V2I32:$Rs, V2I32:$Rt),
3120 (PS_vmulw DoubleRegs:$Rs, DoubleRegs:$Rt)>;
3121def: Pat<(add V2I32:$Rx, (mul V2I32:$Rs, V2I32:$Rt)),
3122 (PS_vmulw_acc DoubleRegs:$Rx, DoubleRegs:$Rs, DoubleRegs:$Rt)>;
3123
3124
3125// Adds two v4i8: Hexagon does not have an insn for this one, so we
3126// use the double add v8i8, and use only the low part of the result.
3127def: Pat<(v4i8 (add (v4i8 IntRegs:$Rs), (v4i8 IntRegs:$Rt))),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003128 (LoReg (A2_vaddub (ToZext64 $Rs), (ToZext64 $Rt)))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003129
3130// Subtract two v4i8: Hexagon does not have an insn for this one, so we
3131// use the double sub v8i8, and use only the low part of the result.
3132def: Pat<(v4i8 (sub (v4i8 IntRegs:$Rs), (v4i8 IntRegs:$Rt))),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003133 (LoReg (A2_vsubub (ToZext64 $Rs), (ToZext64 $Rt)))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003134
3135//
3136// No 32 bit vector mux.
3137//
3138def: Pat<(v4i8 (select I1:$Pu, V4I8:$Rs, V4I8:$Rt)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003139 (LoReg (C2_vmux I1:$Pu, (ToZext64 $Rs), (ToZext64 $Rt)))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003140def: Pat<(v2i16 (select I1:$Pu, V2I16:$Rs, V2I16:$Rt)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003141 (LoReg (C2_vmux I1:$Pu, (ToZext64 $Rs), (ToZext64 $Rt)))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003142
3143//
3144// 64-bit vector mux.
3145//
3146def: Pat<(v8i8 (vselect V8I1:$Pu, V8I8:$Rs, V8I8:$Rt)),
3147 (C2_vmux V8I1:$Pu, V8I8:$Rs, V8I8:$Rt)>;
3148def: Pat<(v4i16 (vselect V4I1:$Pu, V4I16:$Rs, V4I16:$Rt)),
3149 (C2_vmux V4I1:$Pu, V4I16:$Rs, V4I16:$Rt)>;
3150def: Pat<(v2i32 (vselect V2I1:$Pu, V2I32:$Rs, V2I32:$Rt)),
3151 (C2_vmux V2I1:$Pu, V2I32:$Rs, V2I32:$Rt)>;
3152
3153//
3154// No 32 bit vector compare.
3155//
3156def: Pat<(i1 (seteq V4I8:$Rs, V4I8:$Rt)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003157 (A2_vcmpbeq (ToZext64 $Rs), (ToZext64 $Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003158def: Pat<(i1 (setgt V4I8:$Rs, V4I8:$Rt)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003159 (A4_vcmpbgt (ToZext64 $Rs), (ToZext64 $Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003160def: Pat<(i1 (setugt V4I8:$Rs, V4I8:$Rt)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003161 (A2_vcmpbgtu (ToZext64 $Rs), (ToZext64 $Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003162
3163def: Pat<(i1 (seteq V2I16:$Rs, V2I16:$Rt)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003164 (A2_vcmpheq (ToZext64 $Rs), (ToZext64 $Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003165def: Pat<(i1 (setgt V2I16:$Rs, V2I16:$Rt)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003166 (A2_vcmphgt (ToZext64 $Rs), (ToZext64 $Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003167def: Pat<(i1 (setugt V2I16:$Rs, V2I16:$Rt)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003168 (A2_vcmphgtu (ToZext64 $Rs), (ToZext64 $Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003169
3170
3171class InvertCmp_pat<InstHexagon InvMI, PatFrag CmpOp, PatFrag Value,
3172 ValueType CmpTy>
3173 : Pat<(CmpTy (CmpOp Value:$Rs, Value:$Rt)),
3174 (InvMI Value:$Rt, Value:$Rs)>;
3175
3176// Map from a compare operation to the corresponding instruction with the
3177// order of operands reversed, e.g. x > y --> cmp.lt(y,x).
3178def: InvertCmp_pat<A4_vcmpbgt, setlt, V8I8, i1>;
3179def: InvertCmp_pat<A4_vcmpbgt, setlt, V8I8, v8i1>;
3180def: InvertCmp_pat<A2_vcmphgt, setlt, V4I16, i1>;
3181def: InvertCmp_pat<A2_vcmphgt, setlt, V4I16, v4i1>;
3182def: InvertCmp_pat<A2_vcmpwgt, setlt, V2I32, i1>;
3183def: InvertCmp_pat<A2_vcmpwgt, setlt, V2I32, v2i1>;
3184
3185def: InvertCmp_pat<A2_vcmpbgtu, setult, V8I8, i1>;
3186def: InvertCmp_pat<A2_vcmpbgtu, setult, V8I8, v8i1>;
3187def: InvertCmp_pat<A2_vcmphgtu, setult, V4I16, i1>;
3188def: InvertCmp_pat<A2_vcmphgtu, setult, V4I16, v4i1>;
3189def: InvertCmp_pat<A2_vcmpwgtu, setult, V2I32, i1>;
3190def: InvertCmp_pat<A2_vcmpwgtu, setult, V2I32, v2i1>;
3191
3192// Map from vcmpne(Rss) -> !vcmpew(Rss).
3193// rs != rt -> !(rs == rt).
3194def: Pat<(v2i1 (setne V2I32:$Rs, V2I32:$Rt)),
3195 (C2_not (v2i1 (A2_vcmpbeq V2I32:$Rs, V2I32:$Rt)))>;
3196
3197
3198// Truncate: from vector B copy all 'E'ven 'B'yte elements:
3199// A[0] = B[0]; A[1] = B[2]; A[2] = B[4]; A[3] = B[6];
3200def: Pat<(v4i8 (trunc V4I16:$Rs)),
3201 (S2_vtrunehb V4I16:$Rs)>;
3202
3203// Truncate: from vector B copy all 'O'dd 'B'yte elements:
3204// A[0] = B[1]; A[1] = B[3]; A[2] = B[5]; A[3] = B[7];
3205// S2_vtrunohb
3206
3207// Truncate: from vectors B and C copy all 'E'ven 'H'alf-word elements:
3208// A[0] = B[0]; A[1] = B[2]; A[2] = C[0]; A[3] = C[2];
3209// S2_vtruneh
3210
3211def: Pat<(v2i16 (trunc V2I32:$Rs)),
3212 (LoReg (S2_packhl (HiReg $Rs), (LoReg $Rs)))>;
3213
3214
3215def HexagonVSXTBH : SDNode<"HexagonISD::VSXTBH", SDTUnaryOp>;
3216def HexagonVSXTBW : SDNode<"HexagonISD::VSXTBW", SDTUnaryOp>;
3217
3218def: Pat<(i64 (HexagonVSXTBH I32:$Rs)), (S2_vsxtbh I32:$Rs)>;
3219def: Pat<(i64 (HexagonVSXTBW I32:$Rs)), (S2_vsxthw I32:$Rs)>;
3220
3221def: Pat<(v4i16 (zext V4I8:$Rs)), (S2_vzxtbh V4I8:$Rs)>;
3222def: Pat<(v2i32 (zext V2I16:$Rs)), (S2_vzxthw V2I16:$Rs)>;
3223def: Pat<(v4i16 (anyext V4I8:$Rs)), (S2_vzxtbh V4I8:$Rs)>;
3224def: Pat<(v2i32 (anyext V2I16:$Rs)), (S2_vzxthw V2I16:$Rs)>;
3225def: Pat<(v4i16 (sext V4I8:$Rs)), (S2_vsxtbh V4I8:$Rs)>;
3226def: Pat<(v2i32 (sext V2I16:$Rs)), (S2_vsxthw V2I16:$Rs)>;
3227
3228// Sign extends a v2i8 into a v2i32.
3229def: Pat<(v2i32 (sext_inreg V2I32:$Rs, v2i8)),
3230 (A2_combinew (A2_sxtb (HiReg $Rs)), (A2_sxtb (LoReg $Rs)))>;
3231
3232// Sign extends a v2i16 into a v2i32.
3233def: Pat<(v2i32 (sext_inreg V2I32:$Rs, v2i16)),
3234 (A2_combinew (A2_sxth (HiReg $Rs)), (A2_sxth (LoReg $Rs)))>;
3235
3236
3237// Multiplies two v2i16 and returns a v2i32. We are using here the
3238// saturating multiply, as hexagon does not provide a non saturating
3239// vector multiply, and saturation does not impact the result that is
3240// in double precision of the operands.
3241
3242// Multiplies two v2i16 vectors: as Hexagon does not have a multiply
3243// with the C semantics for this one, this pattern uses the half word
3244// multiply vmpyh that takes two v2i16 and returns a v2i32. This is
3245// then truncated to fit this back into a v2i16 and to simulate the
3246// wrap around semantics for unsigned in C.
3247def vmpyh: OutPatFrag<(ops node:$Rs, node:$Rt),
3248 (M2_vmpy2s_s0 (i32 $Rs), (i32 $Rt))>;
3249
3250def: Pat<(v2i16 (mul V2I16:$Rs, V2I16:$Rt)),
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +00003251 (LoReg (S2_vtrunewh (A2_combineii 0, 0),
3252 (vmpyh V2I16:$Rs, V2I16:$Rt)))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003253
3254// Multiplies two v4i16 vectors.
3255def: Pat<(v4i16 (mul V4I16:$Rs, V4I16:$Rt)),
3256 (S2_vtrunewh (vmpyh (HiReg $Rs), (HiReg $Rt)),
3257 (vmpyh (LoReg $Rs), (LoReg $Rt)))>;
3258
3259def VMPYB_no_V5: OutPatFrag<(ops node:$Rs, node:$Rt),
3260 (S2_vtrunewh (vmpyh (HiReg (S2_vsxtbh $Rs)), (HiReg (S2_vsxtbh $Rt))),
3261 (vmpyh (LoReg (S2_vsxtbh $Rs)), (LoReg (S2_vsxtbh $Rt))))>;
3262
3263// Multiplies two v4i8 vectors.
3264def: Pat<(v4i8 (mul V4I8:$Rs, V4I8:$Rt)),
3265 (S2_vtrunehb (M5_vmpybsu V4I8:$Rs, V4I8:$Rt))>,
3266 Requires<[HasV5T]>;
3267
3268def: Pat<(v4i8 (mul V4I8:$Rs, V4I8:$Rt)),
3269 (S2_vtrunehb (VMPYB_no_V5 V4I8:$Rs, V4I8:$Rt))>;
3270
3271// Multiplies two v8i8 vectors.
3272def: Pat<(v8i8 (mul V8I8:$Rs, V8I8:$Rt)),
3273 (A2_combinew (S2_vtrunehb (M5_vmpybsu (HiReg $Rs), (HiReg $Rt))),
3274 (S2_vtrunehb (M5_vmpybsu (LoReg $Rs), (LoReg $Rt))))>,
3275 Requires<[HasV5T]>;
3276
3277def: Pat<(v8i8 (mul V8I8:$Rs, V8I8:$Rt)),
3278 (A2_combinew (S2_vtrunehb (VMPYB_no_V5 (HiReg $Rs), (HiReg $Rt))),
3279 (S2_vtrunehb (VMPYB_no_V5 (LoReg $Rs), (LoReg $Rt))))>;
3280
3281def SDTHexagonBinOp64 : SDTypeProfile<1, 2,
3282 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64>]>;
3283
3284def HexagonSHUFFEB: SDNode<"HexagonISD::SHUFFEB", SDTHexagonBinOp64>;
3285def HexagonSHUFFEH: SDNode<"HexagonISD::SHUFFEH", SDTHexagonBinOp64>;
3286def HexagonSHUFFOB: SDNode<"HexagonISD::SHUFFOB", SDTHexagonBinOp64>;
3287def HexagonSHUFFOH: SDNode<"HexagonISD::SHUFFOH", SDTHexagonBinOp64>;
3288
3289class ShufflePat<InstHexagon MI, SDNode Op>
3290 : Pat<(i64 (Op DoubleRegs:$src1, DoubleRegs:$src2)),
3291 (i64 (MI DoubleRegs:$src1, DoubleRegs:$src2))>;
3292
3293// Shuffles even bytes for i=0..3: A[2*i].b = C[2*i].b; A[2*i+1].b = B[2*i].b
3294def: ShufflePat<S2_shuffeb, HexagonSHUFFEB>;
3295
3296// 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
3297def: ShufflePat<S2_shuffob, HexagonSHUFFOB>;
3298
3299// Shuffles even half for i=0,1: A[2*i].h = C[2*i].h; A[2*i+1].h = B[2*i].h
3300def: ShufflePat<S2_shuffeh, HexagonSHUFFEH>;
3301
3302// 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
3303def: ShufflePat<S2_shuffoh, HexagonSHUFFOH>;
3304
3305
3306// Truncated store from v4i16 to v4i8.
3307def truncstorev4i8: PatFrag<(ops node:$val, node:$ptr),
3308 (truncstore node:$val, node:$ptr),
3309 [{ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v4i8; }]>;
3310
3311// Truncated store from v2i32 to v2i16.
3312def truncstorev2i16: PatFrag<(ops node:$val, node:$ptr),
3313 (truncstore node:$val, node:$ptr),
3314 [{ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v2i16; }]>;
3315
3316def: Pat<(truncstorev2i16 V2I32:$Rs, I32:$Rt),
3317 (S2_storeri_io I32:$Rt, 0, (LoReg (S2_packhl (HiReg $Rs),
3318 (LoReg $Rs))))>;
3319
3320def: Pat<(truncstorev4i8 V4I16:$Rs, I32:$Rt),
3321 (S2_storeri_io I32:$Rt, 0, (S2_vtrunehb V4I16:$Rs))>;
3322
3323
3324// Zero and sign extended load from v2i8 into v2i16.
3325def zextloadv2i8: PatFrag<(ops node:$ptr), (zextload node:$ptr),
3326 [{ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v2i8; }]>;
3327
3328def sextloadv2i8: PatFrag<(ops node:$ptr), (sextload node:$ptr),
3329 [{ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v2i8; }]>;
3330
3331def: Pat<(v2i16 (zextloadv2i8 I32:$Rs)),
3332 (LoReg (v4i16 (S2_vzxtbh (L2_loadruh_io I32:$Rs, 0))))>;
3333
3334def: Pat<(v2i16 (sextloadv2i8 I32:$Rs)),
3335 (LoReg (v4i16 (S2_vsxtbh (L2_loadrh_io I32:$Rs, 0))))>;
3336
3337def: Pat<(v2i32 (zextloadv2i8 I32:$Rs)),
3338 (S2_vzxthw (LoReg (v4i16 (S2_vzxtbh (L2_loadruh_io I32:$Rs, 0)))))>;
3339
3340def: Pat<(v2i32 (sextloadv2i8 I32:$Rs)),
3341 (S2_vsxthw (LoReg (v4i16 (S2_vsxtbh (L2_loadrh_io I32:$Rs, 0)))))>;
3342
Krzysztof Parzyszekab57c2b2017-02-22 22:28:47 +00003343
3344// Read cycle counter.
3345//
3346def SDTInt64Leaf: SDTypeProfile<1, 0, [SDTCisVT<0, i64>]>;
3347def HexagonREADCYCLE: SDNode<"HexagonISD::READCYCLE", SDTInt64Leaf,
3348 [SDNPHasChain]>;
3349
3350def: Pat<(HexagonREADCYCLE), (A4_tfrcpp UPCYCLE)>;