blob: 804a547d5b339110bb83aa4352f956ccae4e260e [file] [log] [blame]
Krzysztof Parzyszek78814152017-06-09 13:30:58 +00001//==- HexagonPatterns.td - Target Description for Hexagon -*- tablegen -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +000010// Pattern fragment that combines the value type and the register class
11// into a single parameter.
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +000012
13// Pattern fragments to extract the low and high subregisters from a
14// 64-bit value.
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +000015def LoReg: OutPatFrag<(ops node:$Rs), (EXTRACT_SUBREG (i64 $Rs), isub_lo)>;
16def HiReg: OutPatFrag<(ops node:$Rs), (EXTRACT_SUBREG (i64 $Rs), isub_hi)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +000017
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +000018def IsOrAdd: PatFrag<(ops node:$Addr, node:$off),
19 (or node:$Addr, node:$off), [{ return isOrEquivalentToAdd(N); }]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +000020
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +000021def Iss4_6 : PatLeaf<(i32 imm), [{
22 int32_t V = N->getSExtValue();
23 return isShiftedInt<4,6>(V);
24}]>;
25
26def Iss4_7 : PatLeaf<(i32 imm), [{
27 int32_t V = N->getSExtValue();
28 return isShiftedInt<4,7>(V);
29}]>;
30
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +000031def IsPow2_32 : PatLeaf<(i32 imm), [{
32 uint32_t V = N->getZExtValue();
33 return isPowerOf2_32(V);
Krzysztof Parzyszek2839b292016-11-05 21:44:50 +000034}]>;
35
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +000036def IsPow2_64 : PatLeaf<(i64 imm), [{
37 uint64_t V = N->getZExtValue();
38 return isPowerOf2_64(V);
39}]>;
40
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +000041def IsNPow2_32 : PatLeaf<(i32 imm), [{
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +000042 uint32_t NV = ~N->getZExtValue();
43 return isPowerOf2_32(NV);
44}]>;
45
46def IsPow2_64L : PatLeaf<(i64 imm), [{
47 uint64_t V = N->getZExtValue();
48 return isPowerOf2_64(V) && Log2_64(V) < 32;
49}]>;
50
51def IsPow2_64H : PatLeaf<(i64 imm), [{
52 uint64_t V = N->getZExtValue();
53 return isPowerOf2_64(V) && Log2_64(V) >= 32;
54}]>;
55
56def IsNPow2_64L : PatLeaf<(i64 imm), [{
57 uint64_t NV = ~N->getZExtValue();
58 return isPowerOf2_64(NV) && Log2_64(NV) < 32;
59}]>;
60
61def IsNPow2_64H : PatLeaf<(i64 imm), [{
62 uint64_t NV = ~N->getZExtValue();
63 return isPowerOf2_64(NV) && Log2_64(NV) >= 32;
Krzysztof Parzyszek2839b292016-11-05 21:44:50 +000064}]>;
65
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +000066def SDEC1 : SDNodeXForm<imm, [{
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +000067 int32_t V = N->getSExtValue();
68 return CurDAG->getTargetConstant(V-1, SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +000069}]>;
70
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +000071def UDEC1 : SDNodeXForm<imm, [{
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +000072 uint32_t V = N->getZExtValue();
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +000073 assert(V >= 1);
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +000074 return CurDAG->getTargetConstant(V-1, SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +000075}]>;
76
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +000077def UDEC32 : SDNodeXForm<imm, [{
78 uint32_t V = N->getZExtValue();
79 assert(V >= 32);
80 return CurDAG->getTargetConstant(V-32, SDLoc(N), MVT::i32);
81}]>;
82
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +000083def Log2_32 : SDNodeXForm<imm, [{
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +000084 uint32_t V = N->getZExtValue();
85 return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32);
86}]>;
87
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +000088def Log2_64 : SDNodeXForm<imm, [{
89 uint64_t V = N->getZExtValue();
90 return CurDAG->getTargetConstant(Log2_64(V), SDLoc(N), MVT::i32);
91}]>;
92
93def LogN2_32 : SDNodeXForm<imm, [{
94 uint32_t NV = ~N->getZExtValue();
95 return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32);
96}]>;
97
98def LogN2_64 : SDNodeXForm<imm, [{
99 uint64_t NV = ~N->getZExtValue();
100 return CurDAG->getTargetConstant(Log2_64(NV), SDLoc(N), MVT::i32);
101}]>;
102
Krzysztof Parzyszekf2086812017-02-28 22:37:01 +0000103def ToZext64: OutPatFrag<(ops node:$Rs),
104 (i64 (A4_combineir 0, (i32 $Rs)))>;
105def ToSext64: OutPatFrag<(ops node:$Rs),
106 (i64 (A2_sxtw (i32 $Rs)))>;
107
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +0000108
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000109class T_CMP_pat <InstHexagon MI, PatFrag OpNode, PatLeaf ImmPred>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000110 : Pat<(i1 (OpNode I32:$src1, ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000111 (MI IntRegs:$src1, ImmPred:$src2)>;
112
113def : T_CMP_pat <C2_cmpeqi, seteq, s10_0ImmPred>;
114def : T_CMP_pat <C2_cmpgti, setgt, s10_0ImmPred>;
115def : T_CMP_pat <C2_cmpgtui, setugt, u9_0ImmPred>;
116
117def SDTHexagonI64I32I32 : SDTypeProfile<1, 2,
118 [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
119
120def HexagonCOMBINE : SDNode<"HexagonISD::COMBINE", SDTHexagonI64I32I32>;
121def HexagonPACKHL : SDNode<"HexagonISD::PACKHL", SDTHexagonI64I32I32>;
122
123// Pats for instruction selection.
124class BinOp32_pat<SDNode Op, InstHexagon MI, ValueType ResT>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000125 : Pat<(ResT (Op I32:$Rs, I32:$Rt)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000126 (ResT (MI IntRegs:$Rs, IntRegs:$Rt))>;
127
128def: BinOp32_pat<add, A2_add, i32>;
129def: BinOp32_pat<and, A2_and, i32>;
130def: BinOp32_pat<or, A2_or, i32>;
131def: BinOp32_pat<sub, A2_sub, i32>;
132def: BinOp32_pat<xor, A2_xor, i32>;
133
134def: BinOp32_pat<HexagonCOMBINE, A2_combinew, i64>;
135def: BinOp32_pat<HexagonPACKHL, S2_packhl, i64>;
136
137// Patfrag to convert the usual comparison patfrags (e.g. setlt) to ones
138// that reverse the order of the operands.
139class RevCmp<PatFrag F> : PatFrag<(ops node:$rhs, node:$lhs), F.Fragment>;
140
141// Pats for compares. They use PatFrags as operands, not SDNodes,
142// since seteq/setgt/etc. are defined as ParFrags.
143class T_cmp32_rr_pat<InstHexagon MI, PatFrag Op, ValueType VT>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000144 : Pat<(VT (Op I32:$Rs, I32:$Rt)),
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000145 (MI IntRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000146
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000147def: T_cmp32_rr_pat<C2_cmpeq, seteq, i1>;
148def: T_cmp32_rr_pat<C2_cmpgt, setgt, i1>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000149def: T_cmp32_rr_pat<C2_cmpgtu, setugt, i1>;
150
151def: T_cmp32_rr_pat<C2_cmpgt, RevCmp<setlt>, i1>;
152def: T_cmp32_rr_pat<C2_cmpgtu, RevCmp<setult>, i1>;
153
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000154def: Pat<(select I1:$Pu, I32:$Rs, I32:$Rt),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000155 (C2_mux PredRegs:$Pu, IntRegs:$Rs, IntRegs:$Rt)>;
156
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000157def: Pat<(add I32:$Rs, s32_0ImmPred:$s16),
158 (A2_addi I32:$Rs, imm:$s16)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000159
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000160def: Pat<(or I32:$Rs, s32_0ImmPred:$s10),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000161 (A2_orir IntRegs:$Rs, imm:$s10)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000162def: Pat<(and I32:$Rs, s32_0ImmPred:$s10),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000163 (A2_andir IntRegs:$Rs, imm:$s10)>;
164
165def: Pat<(sub s32_0ImmPred:$s10, IntRegs:$Rs),
166 (A2_subri imm:$s10, IntRegs:$Rs)>;
167
168// Rd = not(Rs) gets mapped to Rd=sub(#-1, Rs).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000169def: Pat<(not I32:$src1),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000170 (A2_subri -1, IntRegs:$src1)>;
171
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000172def TruncI64ToI32: SDNodeXForm<imm, [{
173 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32);
174}]>;
175
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000176def: Pat<(s32_0ImmPred:$s16), (A2_tfrsi imm:$s16)>;
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000177def: Pat<(s8_0Imm64Pred:$s8), (A2_tfrpi (TruncI64ToI32 $s8))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000178
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000179def : Pat<(select I1:$Pu, s32_0ImmPred:$s8, I32:$Rs),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000180 (C2_muxri I1:$Pu, imm:$s8, I32:$Rs)>;
181
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000182def : Pat<(select I1:$Pu, I32:$Rs, s32_0ImmPred:$s8),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000183 (C2_muxir I1:$Pu, I32:$Rs, imm:$s8)>;
184
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000185def : Pat<(select I1:$Pu, s32_0ImmPred:$s8, s8_0ImmPred:$S8),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000186 (C2_muxii I1:$Pu, imm:$s8, imm:$S8)>;
187
188def: Pat<(shl I32:$src1, (i32 16)), (A2_aslh I32:$src1)>;
189def: Pat<(sra I32:$src1, (i32 16)), (A2_asrh I32:$src1)>;
190def: Pat<(sext_inreg I32:$src1, i8), (A2_sxtb I32:$src1)>;
191def: Pat<(sext_inreg I32:$src1, i16), (A2_sxth I32:$src1)>;
192
193class T_vcmp_pat<InstHexagon MI, PatFrag Op, ValueType T>
194 : Pat<(i1 (Op (T DoubleRegs:$Rss), (T DoubleRegs:$Rtt))),
195 (i1 (MI DoubleRegs:$Rss, DoubleRegs:$Rtt))>;
196
197def: T_vcmp_pat<A2_vcmpbeq, seteq, v8i8>;
198def: T_vcmp_pat<A2_vcmpbgtu, setugt, v8i8>;
199def: T_vcmp_pat<A2_vcmpheq, seteq, v4i16>;
200def: T_vcmp_pat<A2_vcmphgt, setgt, v4i16>;
201def: T_vcmp_pat<A2_vcmphgtu, setugt, v4i16>;
202def: T_vcmp_pat<A2_vcmpweq, seteq, v2i32>;
203def: T_vcmp_pat<A2_vcmpwgt, setgt, v2i32>;
204def: T_vcmp_pat<A2_vcmpwgtu, setugt, v2i32>;
205
206// Add halfword.
207def: Pat<(sext_inreg (add I32:$src1, I32:$src2), i16),
208 (A2_addh_l16_ll I32:$src1, I32:$src2)>;
209
210def: Pat<(sra (add (shl I32:$src1, (i32 16)), I32:$src2), (i32 16)),
211 (A2_addh_l16_hl I32:$src1, I32:$src2)>;
212
213def: Pat<(shl (add I32:$src1, I32:$src2), (i32 16)),
214 (A2_addh_h16_ll I32:$src1, I32:$src2)>;
215
216// Subtract halfword.
217def: Pat<(sext_inreg (sub I32:$src1, I32:$src2), i16),
218 (A2_subh_l16_ll I32:$src1, I32:$src2)>;
219
220def: Pat<(shl (sub I32:$src1, I32:$src2), (i32 16)),
221 (A2_subh_h16_ll I32:$src1, I32:$src2)>;
222
223// Here, depending on the operand being selected, we'll either generate a
224// min or max instruction.
225// Ex:
226// (a>b)?a:b --> max(a,b) => Here check performed is '>' and the value selected
227// is the larger of two. So, the corresponding HexagonInst is passed in 'Inst'.
228// (a>b)?b:a --> min(a,b) => Here check performed is '>' but the smaller value
229// is selected and the corresponding HexagonInst is passed in 'SwapInst'.
230
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000231multiclass T_MinMax_pats <PatFrag Op, PatLeaf Val,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000232 InstHexagon Inst, InstHexagon SwapInst> {
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000233 def: Pat<(select (i1 (Op Val:$src1, Val:$src2)), Val:$src1, Val:$src2),
234 (Inst Val:$src1, Val:$src2)>;
235 def: Pat<(select (i1 (Op Val:$src1, Val:$src2)), Val:$src2, Val:$src1),
236 (SwapInst Val:$src1, Val:$src2)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000237}
238
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000239def IsPosHalf : PatLeaf<(i32 IntRegs:$a), [{
Krzysztof Parzyszek2839b292016-11-05 21:44:50 +0000240 return isPositiveHalfWord(N);
241}]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000242
243multiclass MinMax_pats <PatFrag Op, InstHexagon Inst, InstHexagon SwapInst> {
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000244 defm: T_MinMax_pats<Op, I32, Inst, SwapInst>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000245
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000246 def: Pat<(sext_inreg (select (i1 (Op IsPosHalf:$src1, IsPosHalf:$src2)),
247 IsPosHalf:$src1, IsPosHalf:$src2),
248 i16),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000249 (Inst IntRegs:$src1, IntRegs:$src2)>;
250
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000251 def: Pat<(sext_inreg (select (i1 (Op IsPosHalf:$src1, IsPosHalf:$src2)),
252 IsPosHalf:$src2, IsPosHalf:$src1),
253 i16),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000254 (SwapInst IntRegs:$src1, IntRegs:$src2)>;
255}
256
257let AddedComplexity = 200 in {
258 defm: MinMax_pats<setge, A2_max, A2_min>;
259 defm: MinMax_pats<setgt, A2_max, A2_min>;
260 defm: MinMax_pats<setle, A2_min, A2_max>;
261 defm: MinMax_pats<setlt, A2_min, A2_max>;
262 defm: MinMax_pats<setuge, A2_maxu, A2_minu>;
263 defm: MinMax_pats<setugt, A2_maxu, A2_minu>;
264 defm: MinMax_pats<setule, A2_minu, A2_maxu>;
265 defm: MinMax_pats<setult, A2_minu, A2_maxu>;
266}
267
268class T_cmp64_rr_pat<InstHexagon MI, PatFrag CmpOp>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000269 : Pat<(i1 (CmpOp I64:$Rs, I64:$Rt)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000270 (i1 (MI DoubleRegs:$Rs, DoubleRegs:$Rt))>;
271
272def: T_cmp64_rr_pat<C2_cmpeqp, seteq>;
273def: T_cmp64_rr_pat<C2_cmpgtp, setgt>;
274def: T_cmp64_rr_pat<C2_cmpgtup, setugt>;
275def: T_cmp64_rr_pat<C2_cmpgtp, RevCmp<setlt>>;
276def: T_cmp64_rr_pat<C2_cmpgtup, RevCmp<setult>>;
277
278def: Pat<(i64 (add I64:$Rs, I64:$Rt)), (A2_addp I64:$Rs, I64:$Rt)>;
279def: Pat<(i64 (sub I64:$Rs, I64:$Rt)), (A2_subp I64:$Rs, I64:$Rt)>;
280
281def: Pat<(i64 (and I64:$Rs, I64:$Rt)), (A2_andp I64:$Rs, I64:$Rt)>;
282def: Pat<(i64 (or I64:$Rs, I64:$Rt)), (A2_orp I64:$Rs, I64:$Rt)>;
283def: Pat<(i64 (xor I64:$Rs, I64:$Rt)), (A2_xorp I64:$Rs, I64:$Rt)>;
284
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000285def: Pat<(i1 (not I1:$Ps)), (C2_not PredRegs:$Ps)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000286
287def: Pat<(i1 (and I1:$Ps, I1:$Pt)), (C2_and I1:$Ps, I1:$Pt)>;
288def: Pat<(i1 (or I1:$Ps, I1:$Pt)), (C2_or I1:$Ps, I1:$Pt)>;
289def: Pat<(i1 (xor I1:$Ps, I1:$Pt)), (C2_xor I1:$Ps, I1:$Pt)>;
290def: Pat<(i1 (and I1:$Ps, (not I1:$Pt))), (C2_andn I1:$Ps, I1:$Pt)>;
291def: Pat<(i1 (or I1:$Ps, (not I1:$Pt))), (C2_orn I1:$Ps, I1:$Pt)>;
292
293def retflag : SDNode<"HexagonISD::RET_FLAG", SDTNone,
294 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
295def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone, [SDNPHasChain]>;
296
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000297def: Pat<(br bb:$dst), (J2_jump b30_2Imm:$dst)>;
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000298def: Pat<(brcond I1:$src1, bb:$block), (J2_jumpt PredRegs:$src1, bb:$block)>;
299def: Pat<(brind I32:$dst), (J2_jumpr IntRegs:$dst)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000300
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000301def: Pat<(retflag), (PS_jmpret (i32 R31))>;
302def: Pat<(eh_return), (EH_RETURN_JMPR (i32 R31))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000303
304// Patterns to select load-indexed (i.e. load from base+offset).
305multiclass Loadx_pat<PatFrag Load, ValueType VT, PatLeaf ImmPred,
306 InstHexagon MI> {
307 def: Pat<(VT (Load AddrFI:$fi)), (VT (MI AddrFI:$fi, 0))>;
308 def: Pat<(VT (Load (add (i32 AddrFI:$fi), ImmPred:$Off))),
309 (VT (MI AddrFI:$fi, imm:$Off))>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +0000310 def: Pat<(VT (Load (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000311 (VT (MI AddrFI:$fi, imm:$Off))>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000312 def: Pat<(VT (Load (add I32:$Rs, ImmPred:$Off))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000313 (VT (MI IntRegs:$Rs, imm:$Off))>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000314 def: Pat<(VT (Load I32:$Rs)), (VT (MI IntRegs:$Rs, 0))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000315}
316
317let AddedComplexity = 20 in {
318 defm: Loadx_pat<load, i32, s30_2ImmPred, L2_loadri_io>;
319 defm: Loadx_pat<load, i64, s29_3ImmPred, L2_loadrd_io>;
320 defm: Loadx_pat<atomic_load_8 , i32, s32_0ImmPred, L2_loadrub_io>;
321 defm: Loadx_pat<atomic_load_16, i32, s31_1ImmPred, L2_loadruh_io>;
322 defm: Loadx_pat<atomic_load_32, i32, s30_2ImmPred, L2_loadri_io>;
323 defm: Loadx_pat<atomic_load_64, i64, s29_3ImmPred, L2_loadrd_io>;
324
325 defm: Loadx_pat<extloadi1, i32, s32_0ImmPred, L2_loadrub_io>;
326 defm: Loadx_pat<extloadi8, i32, s32_0ImmPred, L2_loadrub_io>;
327 defm: Loadx_pat<extloadi16, i32, s31_1ImmPred, L2_loadruh_io>;
328 defm: Loadx_pat<sextloadi8, i32, s32_0ImmPred, L2_loadrb_io>;
329 defm: Loadx_pat<sextloadi16, i32, s31_1ImmPred, L2_loadrh_io>;
330 defm: Loadx_pat<zextloadi1, i32, s32_0ImmPred, L2_loadrub_io>;
331 defm: Loadx_pat<zextloadi8, i32, s32_0ImmPred, L2_loadrub_io>;
332 defm: Loadx_pat<zextloadi16, i32, s31_1ImmPred, L2_loadruh_io>;
333 // No sextloadi1.
334}
335
336// Sign-extending loads of i1 need to replicate the lowest bit throughout
337// the 32-bit value. Since the loaded value can only be 0 or 1, 0-v should
338// do the trick.
339let AddedComplexity = 20 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000340def: Pat<(i32 (sextloadi1 I32:$Rs)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000341 (A2_subri 0, (L2_loadrub_io IntRegs:$Rs, 0))>;
342
343def: Pat<(i32 (mul I32:$src1, I32:$src2)), (M2_mpyi I32:$src1, I32:$src2)>;
344def: Pat<(i32 (mulhs I32:$src1, I32:$src2)), (M2_mpy_up I32:$src1, I32:$src2)>;
345def: Pat<(i32 (mulhu I32:$src1, I32:$src2)), (M2_mpyu_up I32:$src1, I32:$src2)>;
346
347def: Pat<(mul IntRegs:$Rs, u32_0ImmPred:$u8),
348 (M2_mpysip IntRegs:$Rs, imm:$u8)>;
349def: Pat<(ineg (mul IntRegs:$Rs, u8_0ImmPred:$u8)),
350 (M2_mpysin IntRegs:$Rs, imm:$u8)>;
351def: Pat<(mul IntRegs:$src1, s32_0ImmPred:$src2),
352 (M2_mpysmi IntRegs:$src1, imm:$src2)>;
353def: Pat<(add (mul IntRegs:$src2, u32_0ImmPred:$src3), IntRegs:$src1),
354 (M2_macsip IntRegs:$src1, IntRegs:$src2, imm:$src3)>;
355def: Pat<(add (mul I32:$src2, I32:$src3), I32:$src1),
356 (M2_maci IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
Krzysztof Parzyszek7aca2fd2017-06-09 15:26:21 +0000357def: Pat<(add (add IntRegs:$src2, s32_0ImmPred:$src3), IntRegs:$src1),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000358 (M2_accii IntRegs:$src1, IntRegs:$src2, imm:$src3)>;
359def: Pat<(add (add I32:$src2, I32:$src3), I32:$src1),
360 (M2_acci IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
361
362class T_MType_acc_pat1 <InstHexagon MI, SDNode firstOp, SDNode secOp,
363 PatLeaf ImmPred>
364 : Pat <(secOp IntRegs:$src1, (firstOp IntRegs:$src2, ImmPred:$src3)),
365 (MI IntRegs:$src1, IntRegs:$src2, ImmPred:$src3)>;
366
367class T_MType_acc_pat2 <InstHexagon MI, SDNode firstOp, SDNode secOp>
368 : Pat <(i32 (secOp IntRegs:$src1, (firstOp IntRegs:$src2, IntRegs:$src3))),
369 (MI IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
370
371def : T_MType_acc_pat2 <M2_xor_xacc, xor, xor>;
372def : T_MType_acc_pat1 <M2_macsin, mul, sub, u32_0ImmPred>;
373
374def : T_MType_acc_pat1 <M2_naccii, add, sub, s32_0ImmPred>;
375def : T_MType_acc_pat2 <M2_nacci, add, sub>;
376
377def: T_MType_acc_pat2 <M4_or_xor, xor, or>;
378def: T_MType_acc_pat2 <M4_and_xor, xor, and>;
379def: T_MType_acc_pat2 <M4_or_and, and, or>;
380def: T_MType_acc_pat2 <M4_and_and, and, and>;
381def: T_MType_acc_pat2 <M4_xor_and, and, xor>;
382def: T_MType_acc_pat2 <M4_or_or, or, or>;
383def: T_MType_acc_pat2 <M4_and_or, or, and>;
384def: T_MType_acc_pat2 <M4_xor_or, or, xor>;
385
386class T_MType_acc_pat3 <InstHexagon MI, SDNode firstOp, SDNode secOp>
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000387 : Pat <(secOp I32:$src1, (firstOp I32:$src2, (not I32:$src3))),
388 (MI IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000389
390def: T_MType_acc_pat3 <M4_or_andn, and, or>;
391def: T_MType_acc_pat3 <M4_and_andn, and, and>;
392def: T_MType_acc_pat3 <M4_xor_andn, and, xor>;
393
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000394// This complex pattern is really only to detect various forms of
395// sign-extension i32->i64. The selected value will be of type i64
396// whose low word is the value being extended. The high word is
397// unspecified.
398def Usxtw : ComplexPattern<i64, 1, "DetectUseSxtw", [], []>;
399
Krzysztof Parzyszek84755102016-11-06 17:56:48 +0000400def Aext64: PatFrag<(ops node:$Rs), (i64 (anyext node:$Rs))>;
Krzysztof Parzyszek84755102016-11-06 17:56:48 +0000401def Zext64: PatFrag<(ops node:$Rs), (i64 (zext node:$Rs))>;
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000402def Sext64: PatLeaf<(i64 Usxtw:$Rs)>;
Krzysztof Parzyszek84755102016-11-06 17:56:48 +0000403
Krzysztof Parzyszekc83c2672017-06-13 16:21:57 +0000404def: Pat<(i32 (trunc (sra (mul Sext64:$Rs, Sext64:$Rt), (i32 32)))),
405 (M2_mpy_up (LoReg Sext64:$Rs), (LoReg Sext64:$Rt))>;
406def: Pat<(i32 (trunc (srl (mul Sext64:$Rs, Sext64:$Rt), (i32 32)))),
407 (M2_mpy_up (LoReg Sext64:$Rs), (LoReg Sext64:$Rt))>;
408
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000409def: Pat<(mul (Aext64 I32:$Rs), (Aext64 I32:$Rt)),
410 (M2_dpmpyuu_s0 I32:$Rs, I32:$Rt)>;
Krzysztof Parzyszek2839b292016-11-05 21:44:50 +0000411
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000412def: Pat<(mul Sext64:$Rs, Sext64:$Rt),
413 (M2_dpmpyss_s0 (LoReg Sext64:$Rs), (LoReg Sext64:$Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000414
415// Multiply and accumulate, use full result.
416// Rxx[+-]=mpy(Rs,Rt)
417
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000418def: Pat<(add I64:$Rx, (mul Sext64:$Rs, Sext64:$Rt)),
419 (M2_dpmpyss_acc_s0 I64:$Rx, (LoReg Sext64:$Rs), (LoReg Sext64:$Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000420
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000421def: Pat<(sub I64:$Rx, (mul Sext64:$Rs, Sext64:$Rt)),
422 (M2_dpmpyss_nac_s0 I64:$Rx, (LoReg Sext64:$Rs), (LoReg Sext64:$Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000423
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000424def: Pat<(add I64:$Rx, (mul (Aext64 I32:$Rs), (Aext64 I32:$Rt))),
425 (M2_dpmpyuu_acc_s0 I64:$Rx, I32:$Rs, I32:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000426
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000427def: Pat<(add I64:$Rx, (mul (Zext64 I32:$Rs), (Zext64 I32:$Rt))),
428 (M2_dpmpyuu_acc_s0 I64:$Rx, I32:$Rs, I32:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000429
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000430def: Pat<(sub I64:$Rx, (mul (Aext64 I32:$Rs), (Aext64 I32:$Rt))),
431 (M2_dpmpyuu_nac_s0 I64:$Rx, I32:$Rs, I32:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000432
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000433def: Pat<(sub I64:$Rx, (mul (Zext64 I32:$Rs), (Zext64 I32:$Rt))),
434 (M2_dpmpyuu_nac_s0 I64:$Rx, I32:$Rs, I32:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000435
436class Storepi_pat<PatFrag Store, PatFrag Value, PatFrag Offset,
437 InstHexagon MI>
438 : Pat<(Store Value:$src1, I32:$src2, Offset:$offset),
439 (MI I32:$src2, imm:$offset, Value:$src1)>;
440
441def: Storepi_pat<post_truncsti8, I32, s4_0ImmPred, S2_storerb_pi>;
442def: Storepi_pat<post_truncsti16, I32, s4_1ImmPred, S2_storerh_pi>;
443def: Storepi_pat<post_store, I32, s4_2ImmPred, S2_storeri_pi>;
444def: Storepi_pat<post_store, I64, s4_3ImmPred, S2_storerd_pi>;
445
446// Patterns for generating stores, where the address takes different forms:
447// - frameindex,
448// - frameindex + offset,
449// - base + offset,
450// - simple (base address without offset).
451// These would usually be used together (via Storex_pat defined below), but
452// in some cases one may want to apply different properties (such as
453// AddedComplexity) to the individual patterns.
454class Storex_fi_pat<PatFrag Store, PatFrag Value, InstHexagon MI>
455 : Pat<(Store Value:$Rs, AddrFI:$fi), (MI AddrFI:$fi, 0, Value:$Rs)>;
456multiclass Storex_fi_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred,
457 InstHexagon MI> {
458 def: Pat<(Store Value:$Rs, (add (i32 AddrFI:$fi), ImmPred:$Off)),
459 (MI AddrFI:$fi, imm:$Off, Value:$Rs)>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +0000460 def: Pat<(Store Value:$Rs, (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000461 (MI AddrFI:$fi, imm:$Off, Value:$Rs)>;
462}
463multiclass Storex_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred,
464 InstHexagon MI> {
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000465 def: Pat<(Store Value:$Rt, (add I32:$Rs, ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000466 (MI IntRegs:$Rs, imm:$Off, Value:$Rt)>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +0000467 def: Pat<(Store Value:$Rt, (IsOrAdd I32:$Rs, ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000468 (MI IntRegs:$Rs, imm:$Off, Value:$Rt)>;
469}
470class Storex_simple_pat<PatFrag Store, PatFrag Value, InstHexagon MI>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000471 : Pat<(Store Value:$Rt, I32:$Rs),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000472 (MI IntRegs:$Rs, 0, Value:$Rt)>;
473
474// Patterns for generating stores, where the address takes different forms,
475// and where the value being stored is transformed through the value modifier
476// ValueMod. The address forms are same as above.
477class Storexm_fi_pat<PatFrag Store, PatFrag Value, PatFrag ValueMod,
478 InstHexagon MI>
479 : Pat<(Store Value:$Rs, AddrFI:$fi),
480 (MI AddrFI:$fi, 0, (ValueMod Value:$Rs))>;
481multiclass Storexm_fi_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred,
482 PatFrag ValueMod, InstHexagon MI> {
483 def: Pat<(Store Value:$Rs, (add (i32 AddrFI:$fi), ImmPred:$Off)),
484 (MI AddrFI:$fi, imm:$Off, (ValueMod Value:$Rs))>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +0000485 def: Pat<(Store Value:$Rs, (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000486 (MI AddrFI:$fi, imm:$Off, (ValueMod Value:$Rs))>;
487}
488multiclass Storexm_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred,
489 PatFrag ValueMod, InstHexagon MI> {
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000490 def: Pat<(Store Value:$Rt, (add I32:$Rs, ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000491 (MI IntRegs:$Rs, imm:$Off, (ValueMod Value:$Rt))>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +0000492 def: Pat<(Store Value:$Rt, (IsOrAdd I32:$Rs, ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000493 (MI IntRegs:$Rs, imm:$Off, (ValueMod Value:$Rt))>;
494}
495class Storexm_simple_pat<PatFrag Store, PatFrag Value, PatFrag ValueMod,
496 InstHexagon MI>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000497 : Pat<(Store Value:$Rt, I32:$Rs),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000498 (MI IntRegs:$Rs, 0, (ValueMod Value:$Rt))>;
499
500multiclass Storex_pat<PatFrag Store, PatFrag Value, PatLeaf ImmPred,
501 InstHexagon MI> {
502 def: Storex_fi_pat <Store, Value, MI>;
503 defm: Storex_fi_add_pat <Store, Value, ImmPred, MI>;
504 defm: Storex_add_pat <Store, Value, ImmPred, MI>;
505}
506
507multiclass Storexm_pat<PatFrag Store, PatFrag Value, PatLeaf ImmPred,
508 PatFrag ValueMod, InstHexagon MI> {
509 def: Storexm_fi_pat <Store, Value, ValueMod, MI>;
510 defm: Storexm_fi_add_pat <Store, Value, ImmPred, ValueMod, MI>;
511 defm: Storexm_add_pat <Store, Value, ImmPred, ValueMod, MI>;
512}
513
514// Regular stores in the DAG have two operands: value and address.
515// Atomic stores also have two, but they are reversed: address, value.
516// To use atomic stores with the patterns, they need to have their operands
517// swapped. This relies on the knowledge that the F.Fragment uses names
518// "ptr" and "val".
519class SwapSt<PatFrag F>
520 : PatFrag<(ops node:$val, node:$ptr), F.Fragment, F.PredicateCode,
521 F.OperandTransform>;
522
523let AddedComplexity = 20 in {
524 defm: Storex_pat<truncstorei8, I32, s32_0ImmPred, S2_storerb_io>;
525 defm: Storex_pat<truncstorei16, I32, s31_1ImmPred, S2_storerh_io>;
526 defm: Storex_pat<store, I32, s30_2ImmPred, S2_storeri_io>;
527 defm: Storex_pat<store, I64, s29_3ImmPred, S2_storerd_io>;
528
529 defm: Storex_pat<SwapSt<atomic_store_8>, I32, s32_0ImmPred, S2_storerb_io>;
530 defm: Storex_pat<SwapSt<atomic_store_16>, I32, s31_1ImmPred, S2_storerh_io>;
531 defm: Storex_pat<SwapSt<atomic_store_32>, I32, s30_2ImmPred, S2_storeri_io>;
532 defm: Storex_pat<SwapSt<atomic_store_64>, I64, s29_3ImmPred, S2_storerd_io>;
533}
534
535// Simple patterns should be tried with the least priority.
536def: Storex_simple_pat<truncstorei8, I32, S2_storerb_io>;
537def: Storex_simple_pat<truncstorei16, I32, S2_storerh_io>;
538def: Storex_simple_pat<store, I32, S2_storeri_io>;
539def: Storex_simple_pat<store, I64, S2_storerd_io>;
540
541def: Storex_simple_pat<SwapSt<atomic_store_8>, I32, S2_storerb_io>;
542def: Storex_simple_pat<SwapSt<atomic_store_16>, I32, S2_storerh_io>;
543def: Storex_simple_pat<SwapSt<atomic_store_32>, I32, S2_storeri_io>;
544def: Storex_simple_pat<SwapSt<atomic_store_64>, I64, S2_storerd_io>;
545
546let AddedComplexity = 20 in {
547 defm: Storexm_pat<truncstorei8, I64, s32_0ImmPred, LoReg, S2_storerb_io>;
548 defm: Storexm_pat<truncstorei16, I64, s31_1ImmPred, LoReg, S2_storerh_io>;
549 defm: Storexm_pat<truncstorei32, I64, s30_2ImmPred, LoReg, S2_storeri_io>;
550}
551
552def: Storexm_simple_pat<truncstorei8, I64, LoReg, S2_storerb_io>;
553def: Storexm_simple_pat<truncstorei16, I64, LoReg, S2_storerh_io>;
554def: Storexm_simple_pat<truncstorei32, I64, LoReg, S2_storeri_io>;
555
Krzysztof Parzyszekef580172017-05-30 17:47:51 +0000556def: Pat <(i64 (sext I32:$src)), (A2_sxtw I32:$src)>;
557def: Pat <(i64 (sext_inreg I64:$src, i32)), (A2_sxtw (LoReg I64:$src))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000558
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000559def: Pat<(select (i1 (setlt I32:$src, 0)), (sub 0, I32:$src), I32:$src),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000560 (A2_abs IntRegs:$src)>;
561
562let AddedComplexity = 50 in
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000563def: Pat<(xor (add (sra I32:$src, (i32 31)),
564 I32:$src),
565 (sra I32:$src, (i32 31))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000566 (A2_abs IntRegs:$src)>;
567
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000568def: Pat<(sra I32:$src, u5_0ImmPred:$u5),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000569 (S2_asr_i_r IntRegs:$src, imm:$u5)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000570def: Pat<(srl I32:$src, u5_0ImmPred:$u5),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000571 (S2_lsr_i_r IntRegs:$src, imm:$u5)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000572def: Pat<(shl I32:$src, u5_0ImmPred:$u5),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000573 (S2_asl_i_r IntRegs:$src, imm:$u5)>;
574
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000575def: Pat<(sra (add (sra I32:$src1, u5_0ImmPred:$src2), 1), (i32 1)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000576 (S2_asr_i_r_rnd IntRegs:$src1, u5_0ImmPred:$src2)>;
577
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000578def : Pat<(not I64:$src1),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000579 (A2_notp DoubleRegs:$src1)>;
580
581// Count leading zeros.
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000582def: Pat<(ctlz I32:$Rs), (S2_cl0 I32:$Rs)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000583def: Pat<(i32 (trunc (ctlz I64:$Rss))), (S2_cl0p I64:$Rss)>;
584
585// Count trailing zeros: 32-bit.
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000586def: Pat<(cttz I32:$Rs), (S2_ct0 I32:$Rs)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000587
588// Count leading ones.
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000589def: Pat<(ctlz (not I32:$Rs)), (S2_cl1 I32:$Rs)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000590def: Pat<(i32 (trunc (ctlz (not I64:$Rss)))), (S2_cl1p I64:$Rss)>;
591
592// Count trailing ones: 32-bit.
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +0000593def: Pat<(cttz (not I32:$Rs)), (S2_ct1 I32:$Rs)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000594
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +0000595let AddedComplexity = 20 in { // Complexity greater than and/or/xor
596 def: Pat<(and I32:$Rs, IsNPow2_32:$V),
597 (S2_clrbit_i IntRegs:$Rs, (LogN2_32 $V))>;
598 def: Pat<(or I32:$Rs, IsPow2_32:$V),
599 (S2_setbit_i IntRegs:$Rs, (Log2_32 $V))>;
600 def: Pat<(xor I32:$Rs, IsPow2_32:$V),
601 (S2_togglebit_i IntRegs:$Rs, (Log2_32 $V))>;
602
603 def: Pat<(and I32:$Rs, (not (shl 1, I32:$Rt))),
604 (S2_clrbit_r IntRegs:$Rs, IntRegs:$Rt)>;
605 def: Pat<(or I32:$Rs, (shl 1, I32:$Rt)),
606 (S2_setbit_r IntRegs:$Rs, IntRegs:$Rt)>;
607 def: Pat<(xor I32:$Rs, (shl 1, I32:$Rt)),
608 (S2_togglebit_r IntRegs:$Rs, IntRegs:$Rt)>;
609}
610
611// Clr/set/toggle bit for 64-bit values with immediate bit index.
612let AddedComplexity = 20 in { // Complexity greater than and/or/xor
613 def: Pat<(and I64:$Rss, IsNPow2_64L:$V),
614 (REG_SEQUENCE DoubleRegs,
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +0000615 (i32 (HiReg $Rss)), isub_hi,
616 (S2_clrbit_i (LoReg $Rss), (LogN2_64 $V)), isub_lo)>;
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +0000617 def: Pat<(and I64:$Rss, IsNPow2_64H:$V),
618 (REG_SEQUENCE DoubleRegs,
619 (S2_clrbit_i (HiReg $Rss), (UDEC32 (i32 (LogN2_64 $V)))),
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +0000620 isub_hi,
621 (i32 (LoReg $Rss)), isub_lo)>;
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +0000622
623 def: Pat<(or I64:$Rss, IsPow2_64L:$V),
624 (REG_SEQUENCE DoubleRegs,
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +0000625 (i32 (HiReg $Rss)), isub_hi,
626 (S2_setbit_i (LoReg $Rss), (Log2_64 $V)), isub_lo)>;
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +0000627 def: Pat<(or I64:$Rss, IsPow2_64H:$V),
628 (REG_SEQUENCE DoubleRegs,
629 (S2_setbit_i (HiReg $Rss), (UDEC32 (i32 (Log2_64 $V)))),
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +0000630 isub_hi,
631 (i32 (LoReg $Rss)), isub_lo)>;
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +0000632
633 def: Pat<(xor I64:$Rss, IsPow2_64L:$V),
634 (REG_SEQUENCE DoubleRegs,
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +0000635 (i32 (HiReg $Rss)), isub_hi,
636 (S2_togglebit_i (LoReg $Rss), (Log2_64 $V)), isub_lo)>;
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +0000637 def: Pat<(xor I64:$Rss, IsPow2_64H:$V),
638 (REG_SEQUENCE DoubleRegs,
639 (S2_togglebit_i (HiReg $Rss), (UDEC32 (i32 (Log2_64 $V)))),
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +0000640 isub_hi,
641 (i32 (LoReg $Rss)), isub_lo)>;
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +0000642}
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000643
644let AddedComplexity = 20 in { // Complexity greater than cmp reg-imm.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000645 def: Pat<(i1 (setne (and (shl 1, u5_0ImmPred:$u5), I32:$Rs), 0)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000646 (S2_tstbit_i IntRegs:$Rs, u5_0ImmPred:$u5)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000647 def: Pat<(i1 (setne (and (shl 1, I32:$Rt), I32:$Rs), 0)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000648 (S2_tstbit_r IntRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000649 def: Pat<(i1 (trunc I32:$Rs)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000650 (S2_tstbit_i IntRegs:$Rs, 0)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000651 def: Pat<(i1 (trunc I64:$Rs)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000652 (S2_tstbit_i (LoReg DoubleRegs:$Rs), 0)>;
653}
654
655let AddedComplexity = 20 in { // Complexity greater than compare reg-imm.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000656 def: Pat<(i1 (seteq (and I32:$Rs, u6_0ImmPred:$u6), 0)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000657 (C2_bitsclri IntRegs:$Rs, u6_0ImmPred:$u6)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000658 def: Pat<(i1 (seteq (and I32:$Rs, I32:$Rt), 0)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000659 (C2_bitsclr IntRegs:$Rs, IntRegs:$Rt)>;
660}
661
662let AddedComplexity = 10 in // Complexity greater than compare reg-reg.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000663def: Pat<(i1 (seteq (and I32:$Rs, I32:$Rt), IntRegs:$Rt)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000664 (C2_bitsset IntRegs:$Rs, IntRegs:$Rt)>;
665
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000666def: Pat<(or (or (shl (or (shl (i32 (extloadi8 (add I32:$b, 3))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000667 (i32 8)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000668 (i32 (zextloadi8 (add I32:$b, 2)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000669 (i32 16)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000670 (shl (i32 (zextloadi8 (add I32:$b, 1))), (i32 8))),
671 (zextloadi8 I32:$b)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000672 (A2_swiz (L2_loadri_io IntRegs:$b, 0))>;
673
674// Patterns for loads of i1:
675def: Pat<(i1 (load AddrFI:$fi)),
676 (C2_tfrrp (L2_loadrub_io AddrFI:$fi, 0))>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000677def: Pat<(i1 (load (add I32:$Rs, s32_0ImmPred:$Off))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000678 (C2_tfrrp (L2_loadrub_io IntRegs:$Rs, imm:$Off))>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000679def: Pat<(i1 (load I32:$Rs)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000680 (C2_tfrrp (L2_loadrub_io IntRegs:$Rs, 0))>;
681
682def I1toI32: OutPatFrag<(ops node:$Rs),
683 (C2_muxii (i1 $Rs), 1, 0)>;
684
685def I32toI1: OutPatFrag<(ops node:$Rs),
686 (i1 (C2_tfrrp (i32 $Rs)))>;
687
688defm: Storexm_pat<store, I1, s32_0ImmPred, I1toI32, S2_storerb_io>;
689def: Storexm_simple_pat<store, I1, I1toI32, S2_storerb_io>;
690
Krzysztof Parzyszek7aca2fd2017-06-09 15:26:21 +0000691def: Pat<(sra (add (sra I64:$src, u6_0ImmPred:$u6), 1), (i32 1)),
692 (S2_asr_i_p_rnd DoubleRegs:$src, imm:$u6)>, Requires<[HasV5T]>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000693def: Pat<(sra I64:$src, u6_0ImmPred:$u6),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000694 (S2_asr_i_p DoubleRegs:$src, imm:$u6)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000695def: Pat<(srl I64:$src, u6_0ImmPred:$u6),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000696 (S2_lsr_i_p DoubleRegs:$src, imm:$u6)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000697def: Pat<(shl I64:$src, u6_0ImmPred:$u6),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000698 (S2_asl_i_p DoubleRegs:$src, imm:$u6)>;
699
700let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000701def: Pat<(add I32:$Rt, (shl I32:$Rs, u3_0ImmPred:$u3)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000702 (S2_addasl_rrri IntRegs:$Rt, IntRegs:$Rs, imm:$u3)>;
703
704def HexagonBARRIER: SDNode<"HexagonISD::BARRIER", SDTNone, [SDNPHasChain]>;
705def: Pat<(HexagonBARRIER), (Y2_barrier)>;
706
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +0000707def: Pat<(IsOrAdd (i32 AddrFI:$Rs), s32_0ImmPred:$off),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000708 (PS_fi (i32 AddrFI:$Rs), s32_0ImmPred:$off)>;
709
710
711// Support for generating global address.
712// Taken from X86InstrInfo.td.
713def SDTHexagonCONST32 : SDTypeProfile<1, 1, [SDTCisVT<0, i32>,
714 SDTCisVT<1, i32>,
715 SDTCisPtrTy<0>]>;
716def HexagonCONST32 : SDNode<"HexagonISD::CONST32", SDTHexagonCONST32>;
717def HexagonCONST32_GP : SDNode<"HexagonISD::CONST32_GP", SDTHexagonCONST32>;
718
719// Map TLS addressses to A2_tfrsi.
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000720def: Pat<(HexagonCONST32 tglobaltlsaddr:$addr), (A2_tfrsi s32_0Imm:$addr)>;
721def: Pat<(HexagonCONST32 bbl:$label), (A2_tfrsi s32_0Imm:$label)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000722
723def: Pat<(i64 imm:$v), (CONST64 imm:$v)>;
724def: Pat<(i1 0), (PS_false)>;
725def: Pat<(i1 1), (PS_true)>;
726
727// Pseudo instructions.
Serge Pavlovd526b132017-05-09 13:35:13 +0000728def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32>,
729 SDTCisVT<1, i32> ]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000730def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>,
731 SDTCisVT<1, i32> ]>;
732
733def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart,
734 [SDNPHasChain, SDNPOutGlue]>;
735def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd,
736 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
737
738def SDT_SPCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
739
740// For tailcalls a HexagonTCRet SDNode has 3 SDNode Properties - a chain,
741// Optional Flag and Variable Arguments.
742// Its 1 Operand has pointer type.
743def HexagonTCRet : SDNode<"HexagonISD::TC_RETURN", SDT_SPCall,
744 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
745
746
Serge Pavlovd526b132017-05-09 13:35:13 +0000747def: Pat<(callseq_start timm:$amt, timm:$amt2),
748 (ADJCALLSTACKDOWN imm:$amt, imm:$amt2)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000749def: Pat<(callseq_end timm:$amt1, timm:$amt2),
750 (ADJCALLSTACKUP imm:$amt1, imm:$amt2)>;
751
752//Tail calls.
753def: Pat<(HexagonTCRet tglobaladdr:$dst),
754 (PS_tailcall_i tglobaladdr:$dst)>;
755def: Pat<(HexagonTCRet texternalsym:$dst),
756 (PS_tailcall_i texternalsym:$dst)>;
757def: Pat<(HexagonTCRet I32:$dst),
758 (PS_tailcall_r I32:$dst)>;
759
760// Map from r0 = and(r1, 65535) to r0 = zxth(r1)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000761def: Pat<(and I32:$src1, 65535),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000762 (A2_zxth IntRegs:$src1)>;
763
764// Map from r0 = and(r1, 255) to r0 = zxtb(r1).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000765def: Pat<(and I32:$src1, 255),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000766 (A2_zxtb IntRegs:$src1)>;
767
768// Map Add(p1, true) to p1 = not(p1).
769// Add(p1, false) should never be produced,
770// if it does, it got to be mapped to NOOP.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000771def: Pat<(add I1:$src1, -1),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000772 (C2_not PredRegs:$src1)>;
773
774// Map from p0 = pnot(p0); r0 = mux(p0, #i, #j) => r0 = mux(p0, #j, #i).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000775def: Pat<(select (not I1:$src1), s8_0ImmPred:$src2, s32_0ImmPred:$src3),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000776 (C2_muxii PredRegs:$src1, s32_0ImmPred:$src3, s8_0ImmPred:$src2)>;
777
778// Map from p0 = pnot(p0); r0 = select(p0, #i, r1)
779// => r0 = C2_muxir(p0, r1, #i)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000780def: Pat<(select (not I1:$src1), s32_0ImmPred:$src2,
781 I32:$src3),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000782 (C2_muxir PredRegs:$src1, IntRegs:$src3, s32_0ImmPred:$src2)>;
783
784// Map from p0 = pnot(p0); r0 = mux(p0, r1, #i)
785// => r0 = C2_muxri (p0, #i, r1)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000786def: Pat<(select (not I1:$src1), IntRegs:$src2, s32_0ImmPred:$src3),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000787 (C2_muxri PredRegs:$src1, s32_0ImmPred:$src3, IntRegs:$src2)>;
788
789// Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000790def: Pat<(brcond (not I1:$src1), bb:$offset),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000791 (J2_jumpf PredRegs:$src1, bb:$offset)>;
792
793// Map from Rdd = sign_extend_inreg(Rss, i32) -> Rdd = A2_sxtw(Rss.lo).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000794def: Pat<(i64 (sext_inreg I64:$src1, i32)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000795 (A2_sxtw (LoReg DoubleRegs:$src1))>;
796
797// Map from Rdd = sign_extend_inreg(Rss, i16) -> Rdd = A2_sxtw(A2_sxth(Rss.lo)).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000798def: Pat<(i64 (sext_inreg I64:$src1, i16)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000799 (A2_sxtw (A2_sxth (LoReg DoubleRegs:$src1)))>;
800
801// Map from Rdd = sign_extend_inreg(Rss, i8) -> Rdd = A2_sxtw(A2_sxtb(Rss.lo)).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000802def: Pat<(i64 (sext_inreg I64:$src1, i8)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000803 (A2_sxtw (A2_sxtb (LoReg DoubleRegs:$src1)))>;
804
Krzysztof Parzyszek7aca2fd2017-06-09 15:26:21 +0000805def: Pat<(brcond (i1 (setne I32:$Rs, I32:$Rt)), bb:$offset),
806 (J2_jumpf (C2_cmpeq I32:$Rs, I32:$Rt), bb:$offset)>;
807def: Pat<(brcond (i1 (setne I32:$Rs, s10_0ImmPred:$s10)), bb:$offset),
808 (J2_jumpf (C2_cmpeqi I32:$Rs, imm:$s10), bb:$offset)>;
809def: Pat<(brcond (i1 (setne I1:$Pu, (i1 -1))), bb:$offset),
810 (J2_jumpf PredRegs:$Pu, bb:$offset)>;
811def: Pat<(brcond (i1 (setne I1:$Pu, (i1 0))), bb:$offset),
812 (J2_jumpt PredRegs:$Pu, bb:$offset)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000813
814// cmp.lt(Rs, Imm) -> !cmp.ge(Rs, Imm) -> !cmp.gt(Rs, Imm-1)
Krzysztof Parzyszek7aca2fd2017-06-09 15:26:21 +0000815def: Pat<(brcond (i1 (setlt I32:$Rs, s8_0ImmPred:$s8)), bb:$offset),
816 (J2_jumpf (C2_cmpgti IntRegs:$Rs, (SDEC1 imm:$s8)), bb:$offset)>;
817
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000818
819// Map from a 64-bit select to an emulated 64-bit mux.
820// Hexagon does not support 64-bit MUXes; so emulate with combines.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000821def: Pat<(select I1:$src1, I64:$src2,
822 I64:$src3),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000823 (A2_combinew (C2_mux PredRegs:$src1, (HiReg DoubleRegs:$src2),
824 (HiReg DoubleRegs:$src3)),
825 (C2_mux PredRegs:$src1, (LoReg DoubleRegs:$src2),
826 (LoReg DoubleRegs:$src3)))>;
827
828// Map from a 1-bit select to logical ops.
829// From LegalizeDAG.cpp: (B1 ? B2 : B3) <=> (B1 & B2)|(!B1&B3).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000830def: Pat<(select I1:$src1, I1:$src2, I1:$src3),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000831 (C2_or (C2_and PredRegs:$src1, PredRegs:$src2),
832 (C2_and (C2_not PredRegs:$src1), PredRegs:$src3))>;
833
834// Map for truncating from 64 immediates to 32 bit immediates.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000835def: Pat<(i32 (trunc I64:$src)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000836 (LoReg DoubleRegs:$src)>;
837
838// Map for truncating from i64 immediates to i1 bit immediates.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000839def: Pat<(i1 (trunc I64:$src)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000840 (C2_tfrrp (LoReg DoubleRegs:$src))>;
841
842// rs <= rt -> !(rs > rt).
843let AddedComplexity = 30 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000844def: Pat<(i1 (setle I32:$src1, s32_0ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000845 (C2_not (C2_cmpgti IntRegs:$src1, s32_0ImmPred:$src2))>;
846
847// rs <= rt -> !(rs > rt).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000848def : Pat<(i1 (setle I32:$src1, I32:$src2)),
849 (i1 (C2_not (C2_cmpgt I32:$src1, I32:$src2)))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000850
851// Rss <= Rtt -> !(Rss > Rtt).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000852def: Pat<(i1 (setle I64:$src1, I64:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000853 (C2_not (C2_cmpgtp DoubleRegs:$src1, DoubleRegs:$src2))>;
854
855// Map cmpne -> cmpeq.
856// Hexagon_TODO: We should improve on this.
857// rs != rt -> !(rs == rt).
858let AddedComplexity = 30 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000859def: Pat<(i1 (setne I32:$src1, s32_0ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000860 (C2_not (C2_cmpeqi IntRegs:$src1, s32_0ImmPred:$src2))>;
861
862// Convert setne back to xor for hexagon since we compute w/ pred registers.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000863def: Pat<(i1 (setne I1:$src1, I1:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000864 (C2_xor PredRegs:$src1, PredRegs:$src2)>;
865
866// Map cmpne(Rss) -> !cmpew(Rss).
867// rs != rt -> !(rs == rt).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000868def: Pat<(i1 (setne I64:$src1, I64:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000869 (C2_not (C2_cmpeqp DoubleRegs:$src1, DoubleRegs:$src2))>;
870
Krzysztof Parzyszek7aca2fd2017-06-09 15:26:21 +0000871// rs >= rt -> rt <= rs
872def: Pat<(i1 (setge I32:$Rs, I32:$Rt)),
873 (C4_cmplte I32:$Rt, I32:$Rs)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000874
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000875let AddedComplexity = 30 in
Krzysztof Parzyszek7aca2fd2017-06-09 15:26:21 +0000876def: Pat<(i1 (setge I32:$Rs, s32_0ImmPred:$s10)),
877 (C2_cmpgti IntRegs:$Rs, (SDEC1 imm:$s10))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000878
879// Map cmpge(Rss, Rtt) -> !cmpgt(Rtt, Rss).
880// rss >= rtt -> !(rtt > rss).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000881def: Pat<(i1 (setge I64:$src1, I64:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000882 (C2_not (C2_cmpgtp DoubleRegs:$src2, DoubleRegs:$src1))>;
883
884// Map cmplt(Rs, Imm) -> !cmpge(Rs, Imm).
885// !cmpge(Rs, Imm) -> !cmpgt(Rs, Imm-1).
886// rs < rt -> !(rs >= rt).
887let AddedComplexity = 30 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000888def: Pat<(i1 (setlt I32:$src1, s32_0ImmPred:$src2)),
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +0000889 (C2_not (C2_cmpgti IntRegs:$src1, (SDEC1 s32_0ImmPred:$src2)))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000890
891// Generate cmpgeu(Rs, #0) -> cmpeq(Rs, Rs)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000892def: Pat<(i1 (setuge I32:$src1, 0)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000893 (C2_cmpeq IntRegs:$src1, IntRegs:$src1)>;
894
895// Generate cmpgeu(Rs, #u8) -> cmpgtu(Rs, #u8 -1)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000896def: Pat<(i1 (setuge I32:$src1, u32_0ImmPred:$src2)),
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +0000897 (C2_cmpgtui IntRegs:$src1, (UDEC1 u32_0ImmPred:$src2))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000898
899// Generate cmpgtu(Rs, #u9)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000900def: Pat<(i1 (setugt I32:$src1, u32_0ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000901 (C2_cmpgtui IntRegs:$src1, u32_0ImmPred:$src2)>;
902
903// Map from Rs >= Rt -> !(Rt > Rs).
904// rs >= rt -> !(rt > rs).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000905def: Pat<(i1 (setuge I64:$src1, I64:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000906 (C2_not (C2_cmpgtup DoubleRegs:$src2, DoubleRegs:$src1))>;
907
908// Map from cmpleu(Rss, Rtt) -> !cmpgtu(Rss, Rtt-1).
909// Map from (Rs <= Rt) -> !(Rs > Rt).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000910def: Pat<(i1 (setule I64:$src1, I64:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000911 (C2_not (C2_cmpgtup DoubleRegs:$src1, DoubleRegs:$src2))>;
912
913// Sign extends.
Krzysztof Parzyszekf2086812017-02-28 22:37:01 +0000914// sext i1->i32
915def: Pat<(i32 (sext I1:$Pu)),
916 (C2_muxii I1:$Pu, -1, 0)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000917
Krzysztof Parzyszekf2086812017-02-28 22:37:01 +0000918// sext i1->i64
919def: Pat<(i64 (sext I1:$Pu)),
920 (A2_combinew (C2_muxii PredRegs:$Pu, -1, 0),
921 (C2_muxii PredRegs:$Pu, -1, 0))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000922
923// Zero extends.
Krzysztof Parzyszekf2086812017-02-28 22:37:01 +0000924// zext i1->i32
925def: Pat<(i32 (zext I1:$Pu)),
926 (C2_muxii PredRegs:$Pu, 1, 0)>;
927
928// zext i1->i64
929def: Pat<(i64 (zext I1:$Pu)),
930 (ToZext64 (C2_muxii PredRegs:$Pu, 1, 0))>;
931
932// zext i32->i64
933def: Pat<(Zext64 I32:$Rs),
934 (ToZext64 IntRegs:$Rs)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000935
936// Map from Rs = Pd to Pd = mux(Pd, #1, #0)
Krzysztof Parzyszekf2086812017-02-28 22:37:01 +0000937def: Pat<(i32 (anyext I1:$Pu)),
938 (C2_muxii PredRegs:$Pu, 1, 0)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000939
Krzysztof Parzyszekf2086812017-02-28 22:37:01 +0000940// Map from Rss = Pd to Rdd = combine(#0, (mux(Pd, #1, #0)))
941def: Pat<(i64 (anyext I1:$Pu)),
942 (ToZext64 (C2_muxii PredRegs:$Pu, 1, 0))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000943
944// Clear the sign bit in a 64-bit register.
945def ClearSign : OutPatFrag<(ops node:$Rss),
946 (A2_combinew (S2_clrbit_i (HiReg $Rss), 31), (LoReg $Rss))>;
947
948def MulHU : OutPatFrag<(ops node:$Rss, node:$Rtt),
949 (A2_addp
950 (M2_dpmpyuu_acc_s0
951 (S2_lsr_i_p
952 (A2_addp
953 (M2_dpmpyuu_acc_s0
954 (S2_lsr_i_p (M2_dpmpyuu_s0 (LoReg $Rss), (LoReg $Rtt)), 32),
955 (HiReg $Rss),
956 (LoReg $Rtt)),
957 (A2_combinew (A2_tfrsi 0),
958 (LoReg (M2_dpmpyuu_s0 (LoReg $Rss), (HiReg $Rtt))))),
959 32),
960 (HiReg $Rss),
961 (HiReg $Rtt)),
962 (S2_lsr_i_p (M2_dpmpyuu_s0 (LoReg $Rss), (HiReg $Rtt)), 32))>;
963
964// Multiply 64-bit unsigned and use upper result.
965def : Pat <(mulhu I64:$Rss, I64:$Rtt), (MulHU $Rss, $Rtt)>;
966
967// Multiply 64-bit signed and use upper result.
968//
969// For two signed 64-bit integers A and B, let A' and B' denote A and B
970// with the sign bit cleared. Then A = -2^63*s(A) + A', where s(A) is the
971// sign bit of A (and identically for B). With this notation, the signed
972// product A*B can be written as:
973// AB = (-2^63 s(A) + A') * (-2^63 s(B) + B')
974// = 2^126 s(A)s(B) - 2^63 [s(A)B'+s(B)A'] + A'B'
975// = 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']
976// = (unsigned product AB) - 2^64 [s(A)B'+s(B)A']
977
978def : Pat <(mulhs I64:$Rss, I64:$Rtt),
979 (A2_subp
980 (MulHU $Rss, $Rtt),
981 (A2_addp
982 (A2_andp (S2_asr_i_p $Rss, 63), (ClearSign $Rtt)),
983 (A2_andp (S2_asr_i_p $Rtt, 63), (ClearSign $Rss))))>;
984
985// Hexagon specific ISD nodes.
986def SDTHexagonALLOCA : SDTypeProfile<1, 2,
987 [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
988def HexagonALLOCA : SDNode<"HexagonISD::ALLOCA", SDTHexagonALLOCA,
989 [SDNPHasChain]>;
990
991
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +0000992def: Pat<(HexagonALLOCA I32:$Rs, (i32 imm:$A)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +0000993 (PS_alloca IntRegs:$Rs, imm:$A)>;
994
995def HexagonJT: SDNode<"HexagonISD::JT", SDTIntUnaryOp>;
996def HexagonCP: SDNode<"HexagonISD::CP", SDTIntUnaryOp>;
997
998def: Pat<(HexagonJT tjumptable:$dst), (A2_tfrsi imm:$dst)>;
999def: Pat<(HexagonCP tconstpool:$dst), (A2_tfrsi imm:$dst)>;
1000
1001let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001002def: Pat<(add I32:$src1, (sra I32:$Rs, u5_0ImmPred:$u5)), (S2_asr_i_r_acc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1003def: Pat<(sub I32:$src1, (sra I32:$Rs, u5_0ImmPred:$u5)), (S2_asr_i_r_nac IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1004def: Pat<(and I32:$src1, (sra I32:$Rs, u5_0ImmPred:$u5)), (S2_asr_i_r_and IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1005def: 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 +00001006
1007let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001008def: Pat<(add I64:$src1, (sra I64:$Rs, u6_0ImmPred:$u5)), (S2_asr_i_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1009def: Pat<(sub I64:$src1, (sra I64:$Rs, u6_0ImmPred:$u5)), (S2_asr_i_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1010def: Pat<(and I64:$src1, (sra I64:$Rs, u6_0ImmPred:$u5)), (S2_asr_i_p_and DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1011def: 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 +00001012
1013let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001014def: Pat<(add I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_acc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1015def: Pat<(sub I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_nac IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1016def: Pat<(and I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_and IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1017def: 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 +00001018let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001019def: 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 +00001020
1021let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001022def: Pat<(add I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1023def: Pat<(sub I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1024def: Pat<(and I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_and DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1025def: 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 +00001026let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001027def: 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 +00001028
1029let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001030def: Pat<(add I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_acc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1031def: Pat<(sub I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_nac IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1032def: Pat<(and I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_and IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>;
1033def: 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 +00001034let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001035def: 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 +00001036
1037let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001038def: Pat<(add I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1039def: Pat<(sub I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1040def: Pat<(and I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_and DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>;
1041def: 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 +00001042let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001043def: 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 +00001044
1045let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001046def: Pat<(add I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_asl_r_r_acc IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1047def: Pat<(sub I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_asl_r_r_nac IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1048def: Pat<(and I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_asl_r_r_and IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1049def: 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 +00001050let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001051def: Pat<(add I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1052def: Pat<(sub I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1053def: Pat<(and I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_and DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1054def: Pat<(or I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_or DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1055def: 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 +00001056
1057let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001058def: Pat<(add I32:$src1, (sra I32:$Rs, I32:$Rt)), (S2_asr_r_r_acc IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1059def: Pat<(sub I32:$src1, (sra I32:$Rs, I32:$Rt)), (S2_asr_r_r_nac IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1060def: Pat<(and I32:$src1, (sra I32:$Rs, I32:$Rt)), (S2_asr_r_r_and IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1061def: 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 +00001062let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001063def: Pat<(add I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1064def: Pat<(sub I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1065def: Pat<(and I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_and DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1066def: Pat<(or I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_or DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1067def: 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 +00001068
1069let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001070def: Pat<(add I32:$src1, (srl I32:$Rs, I32:$Rt)), (S2_lsr_r_r_acc IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1071def: Pat<(sub I32:$src1, (srl I32:$Rs, I32:$Rt)), (S2_lsr_r_r_nac IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1072def: Pat<(and I32:$src1, (srl I32:$Rs, I32:$Rt)), (S2_lsr_r_r_and IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1073def: 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 +00001074let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001075def: Pat<(add I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1076def: Pat<(sub I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1077def: Pat<(and I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_and DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1078def: Pat<(or I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_or DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1079def: 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 +00001080
1081let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001082def: Pat<(add I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_lsl_r_r_acc IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1083def: Pat<(sub I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_lsl_r_r_nac IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1084def: Pat<(and I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_lsl_r_r_and IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>;
1085def: 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 +00001086let AddedComplexity = 100 in
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001087def: Pat<(add I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1088def: Pat<(sub I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1089def: Pat<(and I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_and DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1090def: Pat<(or I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_or DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>;
1091def: 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 +00001092
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001093def: Pat<(sra I64:$src1, I32:$src2), (S2_asr_r_p DoubleRegs:$src1, IntRegs:$src2)>;
1094def: Pat<(srl I64:$src1, I32:$src2), (S2_lsr_r_p DoubleRegs:$src1, IntRegs:$src2)>;
1095def: Pat<(shl I64:$src1, I32:$src2), (S2_asl_r_p DoubleRegs:$src1, IntRegs:$src2)>;
1096def: Pat<(shl I64:$src1, I32:$src2), (S2_lsl_r_p DoubleRegs:$src1, IntRegs:$src2)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001097
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001098def: Pat<(sra I32:$src1, I32:$src2), (S2_asr_r_r IntRegs:$src1, IntRegs:$src2)>;
1099def: Pat<(srl I32:$src1, I32:$src2), (S2_lsr_r_r IntRegs:$src1, IntRegs:$src2)>;
1100def: Pat<(shl I32:$src1, I32:$src2), (S2_asl_r_r IntRegs:$src1, IntRegs:$src2)>;
1101def: Pat<(shl I32:$src1, I32:$src2), (S2_lsl_r_r IntRegs:$src1, IntRegs:$src2)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001102
1103def SDTHexagonINSERT:
1104 SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
1105 SDTCisInt<0>, SDTCisVT<3, i32>, SDTCisVT<4, i32>]>;
1106def SDTHexagonINSERTRP:
1107 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
1108 SDTCisInt<0>, SDTCisVT<3, i64>]>;
1109
1110def HexagonINSERT : SDNode<"HexagonISD::INSERT", SDTHexagonINSERT>;
1111def HexagonINSERTRP : SDNode<"HexagonISD::INSERTRP", SDTHexagonINSERTRP>;
1112
1113def: Pat<(HexagonINSERT I32:$Rs, I32:$Rt, u5_0ImmPred:$u1, u5_0ImmPred:$u2),
1114 (S2_insert I32:$Rs, I32:$Rt, u5_0ImmPred:$u1, u5_0ImmPred:$u2)>;
1115def: Pat<(HexagonINSERT I64:$Rs, I64:$Rt, u6_0ImmPred:$u1, u6_0ImmPred:$u2),
1116 (S2_insertp I64:$Rs, I64:$Rt, u6_0ImmPred:$u1, u6_0ImmPred:$u2)>;
1117def: Pat<(HexagonINSERTRP I32:$Rs, I32:$Rt, I64:$Ru),
1118 (S2_insert_rp I32:$Rs, I32:$Rt, I64:$Ru)>;
1119def: Pat<(HexagonINSERTRP I64:$Rs, I64:$Rt, I64:$Ru),
1120 (S2_insertp_rp I64:$Rs, I64:$Rt, I64:$Ru)>;
1121
1122let AddedComplexity = 100 in
1123def: Pat<(or (or (shl (HexagonINSERT (i32 (zextloadi8 (add I32:$b, 2))),
1124 (i32 (extloadi8 (add I32:$b, 3))),
1125 24, 8),
1126 (i32 16)),
1127 (shl (i32 (zextloadi8 (add I32:$b, 1))), (i32 8))),
1128 (zextloadi8 I32:$b)),
1129 (A2_swiz (L2_loadri_io I32:$b, 0))>;
1130
1131def SDTHexagonEXTRACTU:
1132 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<1>,
1133 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
1134def SDTHexagonEXTRACTURP:
1135 SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<1>,
1136 SDTCisVT<2, i64>]>;
1137
1138def HexagonEXTRACTU : SDNode<"HexagonISD::EXTRACTU", SDTHexagonEXTRACTU>;
1139def HexagonEXTRACTURP : SDNode<"HexagonISD::EXTRACTURP", SDTHexagonEXTRACTURP>;
1140
1141def: Pat<(HexagonEXTRACTU I32:$src1, u5_0ImmPred:$src2, u5_0ImmPred:$src3),
1142 (S2_extractu I32:$src1, u5_0ImmPred:$src2, u5_0ImmPred:$src3)>;
1143def: Pat<(HexagonEXTRACTU I64:$src1, u6_0ImmPred:$src2, u6_0ImmPred:$src3),
1144 (S2_extractup I64:$src1, u6_0ImmPred:$src2, u6_0ImmPred:$src3)>;
1145def: Pat<(HexagonEXTRACTURP I32:$src1, I64:$src2),
1146 (S2_extractu_rp I32:$src1, I64:$src2)>;
1147def: Pat<(HexagonEXTRACTURP I64:$src1, I64:$src2),
1148 (S2_extractup_rp I64:$src1, I64:$src2)>;
1149
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00001150def n8_0ImmPred: PatLeaf<(i32 imm), [{
1151 int64_t V = N->getSExtValue();
1152 return -255 <= V && V <= 0;
1153}]>;
1154
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001155// Change the sign of the immediate for Rd=-mpyi(Rs,#u8)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001156def: Pat<(mul I32:$src1, (ineg n8_0ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001157 (M2_mpysin IntRegs:$src1, u8_0ImmPred:$src2)>;
1158
1159multiclass MinMax_pats_p<PatFrag Op, InstHexagon Inst, InstHexagon SwapInst> {
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +00001160 defm: T_MinMax_pats<Op, I64, Inst, SwapInst>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001161}
1162
Krzysztof Parzyszekef580172017-05-30 17:47:51 +00001163def: Pat<(add Sext64:$Rs, I64:$Rt),
1164 (A2_addsp (LoReg Sext64:$Rs), DoubleRegs:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001165
1166let AddedComplexity = 200 in {
1167 defm: MinMax_pats_p<setge, A2_maxp, A2_minp>;
1168 defm: MinMax_pats_p<setgt, A2_maxp, A2_minp>;
1169 defm: MinMax_pats_p<setle, A2_minp, A2_maxp>;
1170 defm: MinMax_pats_p<setlt, A2_minp, A2_maxp>;
1171 defm: MinMax_pats_p<setuge, A2_maxup, A2_minup>;
1172 defm: MinMax_pats_p<setugt, A2_maxup, A2_minup>;
1173 defm: MinMax_pats_p<setule, A2_minup, A2_maxup>;
1174 defm: MinMax_pats_p<setult, A2_minup, A2_maxup>;
1175}
1176
1177def callv3 : SDNode<"HexagonISD::CALL", SDT_SPCall,
1178 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;
1179
1180def callv3nr : SDNode<"HexagonISD::CALLnr", SDT_SPCall,
1181 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;
1182
1183
1184// Map call instruction
1185def : Pat<(callv3 I32:$dst),
1186 (J2_callr I32:$dst)>;
1187def : Pat<(callv3 tglobaladdr:$dst),
1188 (J2_call tglobaladdr:$dst)>;
1189def : Pat<(callv3 texternalsym:$dst),
1190 (J2_call texternalsym:$dst)>;
1191def : Pat<(callv3 tglobaltlsaddr:$dst),
1192 (J2_call tglobaltlsaddr:$dst)>;
1193
1194def : Pat<(callv3nr I32:$dst),
1195 (PS_callr_nr I32:$dst)>;
1196def : Pat<(callv3nr tglobaladdr:$dst),
1197 (PS_call_nr tglobaladdr:$dst)>;
1198def : Pat<(callv3nr texternalsym:$dst),
1199 (PS_call_nr texternalsym:$dst)>;
1200
1201
1202def addrga: PatLeaf<(i32 AddrGA:$Addr)>;
1203def addrgp: PatLeaf<(i32 AddrGP:$Addr)>;
1204
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001205
1206// Pats for instruction selection.
1207
1208// A class to embed the usual comparison patfrags within a zext to i32.
1209// The seteq/setne frags use "lhs" and "rhs" as operands, so use the same
1210// names, or else the frag's "body" won't match the operands.
1211class CmpInReg<PatFrag Op>
1212 : PatFrag<(ops node:$lhs, node:$rhs),(i32 (zext (i1 Op.Fragment)))>;
1213
1214def: T_cmp32_rr_pat<A4_rcmpeq, CmpInReg<seteq>, i32>;
1215def: T_cmp32_rr_pat<A4_rcmpneq, CmpInReg<setne>, i32>;
1216
1217def: T_cmp32_rr_pat<C4_cmpneq, setne, i1>;
1218def: T_cmp32_rr_pat<C4_cmplte, setle, i1>;
1219def: T_cmp32_rr_pat<C4_cmplteu, setule, i1>;
1220
1221def: T_cmp32_rr_pat<C4_cmplte, RevCmp<setge>, i1>;
1222def: T_cmp32_rr_pat<C4_cmplteu, RevCmp<setuge>, i1>;
1223
1224let AddedComplexity = 100 in {
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 255), 0)),
1227 (A4_cmpbeq 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 255), 0)),
1230 (C2_not (A4_cmpbeq IntRegs:$Rs, IntRegs:$Rt))>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001231 def: Pat<(i1 (seteq (and (xor I32:$Rs, I32:$Rt),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001232 65535), 0)),
1233 (A4_cmpheq IntRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001234 def: Pat<(i1 (setne (and (xor I32:$Rs, I32:$Rt),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001235 65535), 0)),
1236 (C2_not (A4_cmpheq IntRegs:$Rs, IntRegs:$Rt))>;
1237}
1238
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001239def: Pat<(i32 (zext (i1 (seteq I32:$Rs, s32_0ImmPred:$s8)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001240 (A4_rcmpeqi IntRegs:$Rs, s32_0ImmPred:$s8)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001241def: Pat<(i32 (zext (i1 (setne I32:$Rs, s32_0ImmPred:$s8)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001242 (A4_rcmpneqi IntRegs:$Rs, s32_0ImmPred:$s8)>;
1243
1244// Preserve the S2_tstbit_r generation
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001245def: Pat<(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, I32:$src2)),
1246 I32:$src1)), 0)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001247 (C2_muxii (S2_tstbit_r IntRegs:$src1, IntRegs:$src2), 1, 0)>;
1248
1249// The complexity of the combines involving immediates should be greater
1250// than the complexity of the combine with two registers.
1251let AddedComplexity = 50 in {
1252def: Pat<(HexagonCOMBINE IntRegs:$r, s32_0ImmPred:$i),
1253 (A4_combineri IntRegs:$r, s32_0ImmPred:$i)>;
1254
1255def: Pat<(HexagonCOMBINE s32_0ImmPred:$i, IntRegs:$r),
1256 (A4_combineir s32_0ImmPred:$i, IntRegs:$r)>;
1257}
1258
1259// The complexity of the combine with two immediates should be greater than
1260// the complexity of a combine involving a register.
1261let AddedComplexity = 75 in {
1262def: Pat<(HexagonCOMBINE s8_0ImmPred:$s8, u32_0ImmPred:$u6),
1263 (A4_combineii imm:$s8, imm:$u6)>;
1264def: Pat<(HexagonCOMBINE s32_0ImmPred:$s8, s8_0ImmPred:$S8),
1265 (A2_combineii imm:$s8, imm:$S8)>;
1266}
1267
1268
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001269// Patterns to generate indexed loads with different forms of the address:
1270// - frameindex,
1271// - base + offset,
1272// - base (without offset).
1273multiclass Loadxm_pat<PatFrag Load, ValueType VT, PatFrag ValueMod,
1274 PatLeaf ImmPred, InstHexagon MI> {
1275 def: Pat<(VT (Load AddrFI:$fi)),
1276 (VT (ValueMod (MI AddrFI:$fi, 0)))>;
1277 def: Pat<(VT (Load (add AddrFI:$fi, ImmPred:$Off))),
1278 (VT (ValueMod (MI AddrFI:$fi, imm:$Off)))>;
1279 def: Pat<(VT (Load (add IntRegs:$Rs, ImmPred:$Off))),
1280 (VT (ValueMod (MI IntRegs:$Rs, imm:$Off)))>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001281 def: Pat<(VT (Load I32:$Rs)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001282 (VT (ValueMod (MI IntRegs:$Rs, 0)))>;
1283}
1284
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001285defm: Loadxm_pat<extloadi1, i64, ToZext64, s32_0ImmPred, L2_loadrub_io>;
1286defm: Loadxm_pat<extloadi8, i64, ToZext64, s32_0ImmPred, L2_loadrub_io>;
1287defm: Loadxm_pat<extloadi16, i64, ToZext64, s31_1ImmPred, L2_loadruh_io>;
1288defm: Loadxm_pat<zextloadi1, i64, ToZext64, s32_0ImmPred, L2_loadrub_io>;
1289defm: Loadxm_pat<zextloadi8, i64, ToZext64, s32_0ImmPred, L2_loadrub_io>;
1290defm: Loadxm_pat<zextloadi16, i64, ToZext64, s31_1ImmPred, L2_loadruh_io>;
1291defm: Loadxm_pat<sextloadi8, i64, ToSext64, s32_0ImmPred, L2_loadrb_io>;
1292defm: Loadxm_pat<sextloadi16, i64, ToSext64, s31_1ImmPred, L2_loadrh_io>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001293
1294// Map Rdd = anyext(Rs) -> Rdd = combine(#0, Rs).
Krzysztof Parzyszek84755102016-11-06 17:56:48 +00001295def: Pat<(Aext64 I32:$src1), (ToZext64 IntRegs:$src1)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001296
1297multiclass T_LoadAbsReg_Pat <PatFrag ldOp, InstHexagon MI, ValueType VT = i32> {
1298 def : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2_0ImmPred:$src2),
1299 (HexagonCONST32 tglobaladdr:$src3)))),
1300 (MI IntRegs:$src1, u2_0ImmPred:$src2, tglobaladdr:$src3)>;
1301 def : Pat <(VT (ldOp (add IntRegs:$src1,
1302 (HexagonCONST32 tglobaladdr:$src2)))),
1303 (MI IntRegs:$src1, 0, tglobaladdr:$src2)>;
1304
1305 def : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2_0ImmPred:$src2),
1306 (HexagonCONST32 tconstpool:$src3)))),
1307 (MI IntRegs:$src1, u2_0ImmPred:$src2, tconstpool:$src3)>;
1308 def : Pat <(VT (ldOp (add IntRegs:$src1,
1309 (HexagonCONST32 tconstpool:$src2)))),
1310 (MI IntRegs:$src1, 0, tconstpool:$src2)>;
1311
1312 def : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2_0ImmPred:$src2),
1313 (HexagonCONST32 tjumptable:$src3)))),
1314 (MI IntRegs:$src1, u2_0ImmPred:$src2, tjumptable:$src3)>;
1315 def : Pat <(VT (ldOp (add IntRegs:$src1,
1316 (HexagonCONST32 tjumptable:$src2)))),
1317 (MI IntRegs:$src1, 0, tjumptable:$src2)>;
1318}
1319
1320let AddedComplexity = 60 in {
1321defm : T_LoadAbsReg_Pat <sextloadi8, L4_loadrb_ur>;
1322defm : T_LoadAbsReg_Pat <zextloadi8, L4_loadrub_ur>;
1323defm : T_LoadAbsReg_Pat <extloadi8, L4_loadrub_ur>;
1324
1325defm : T_LoadAbsReg_Pat <sextloadi16, L4_loadrh_ur>;
1326defm : T_LoadAbsReg_Pat <zextloadi16, L4_loadruh_ur>;
1327defm : T_LoadAbsReg_Pat <extloadi16, L4_loadruh_ur>;
1328
1329defm : T_LoadAbsReg_Pat <load, L4_loadri_ur>;
1330defm : T_LoadAbsReg_Pat <load, L4_loadrd_ur, i64>;
1331}
1332
1333// 'def pats' for load instructions with base + register offset and non-zero
1334// immediate value. Immediate value is used to left-shift the second
1335// register operand.
1336class Loadxs_pat<PatFrag Load, ValueType VT, InstHexagon MI>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001337 : Pat<(VT (Load (add I32:$Rs,
1338 (i32 (shl I32:$Rt, u2_0ImmPred:$u2))))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001339 (VT (MI IntRegs:$Rs, IntRegs:$Rt, imm:$u2))>;
1340
1341let AddedComplexity = 40 in {
1342 def: Loadxs_pat<extloadi8, i32, L4_loadrub_rr>;
1343 def: Loadxs_pat<zextloadi8, i32, L4_loadrub_rr>;
1344 def: Loadxs_pat<sextloadi8, i32, L4_loadrb_rr>;
1345 def: Loadxs_pat<extloadi16, i32, L4_loadruh_rr>;
1346 def: Loadxs_pat<zextloadi16, i32, L4_loadruh_rr>;
1347 def: Loadxs_pat<sextloadi16, i32, L4_loadrh_rr>;
1348 def: Loadxs_pat<load, i32, L4_loadri_rr>;
1349 def: Loadxs_pat<load, i64, L4_loadrd_rr>;
1350}
1351
1352// 'def pats' for load instruction base + register offset and
1353// zero immediate value.
1354class Loadxs_simple_pat<PatFrag Load, ValueType VT, InstHexagon MI>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001355 : Pat<(VT (Load (add I32:$Rs, I32:$Rt))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001356 (VT (MI IntRegs:$Rs, IntRegs:$Rt, 0))>;
1357
1358let AddedComplexity = 20 in {
1359 def: Loadxs_simple_pat<extloadi8, i32, L4_loadrub_rr>;
1360 def: Loadxs_simple_pat<zextloadi8, i32, L4_loadrub_rr>;
1361 def: Loadxs_simple_pat<sextloadi8, i32, L4_loadrb_rr>;
1362 def: Loadxs_simple_pat<extloadi16, i32, L4_loadruh_rr>;
1363 def: Loadxs_simple_pat<zextloadi16, i32, L4_loadruh_rr>;
1364 def: Loadxs_simple_pat<sextloadi16, i32, L4_loadrh_rr>;
1365 def: Loadxs_simple_pat<load, i32, L4_loadri_rr>;
1366 def: Loadxs_simple_pat<load, i64, L4_loadrd_rr>;
1367}
1368
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001369let AddedComplexity = 40 in
1370multiclass T_StoreAbsReg_Pats <InstHexagon MI, RegisterClass RC, ValueType VT,
1371 PatFrag stOp> {
1372 def : Pat<(stOp (VT RC:$src4),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001373 (add (shl I32:$src1, u2_0ImmPred:$src2),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001374 u32_0ImmPred:$src3)),
1375 (MI IntRegs:$src1, u2_0ImmPred:$src2, u32_0ImmPred:$src3, RC:$src4)>;
1376
1377 def : Pat<(stOp (VT RC:$src4),
1378 (add (shl IntRegs:$src1, u2_0ImmPred:$src2),
1379 (HexagonCONST32 tglobaladdr:$src3))),
1380 (MI IntRegs:$src1, u2_0ImmPred:$src2, tglobaladdr:$src3, RC:$src4)>;
1381
1382 def : Pat<(stOp (VT RC:$src4),
1383 (add IntRegs:$src1, (HexagonCONST32 tglobaladdr:$src3))),
1384 (MI IntRegs:$src1, 0, tglobaladdr:$src3, RC:$src4)>;
1385}
1386
1387defm : T_StoreAbsReg_Pats <S4_storerd_ur, DoubleRegs, i64, store>;
1388defm : T_StoreAbsReg_Pats <S4_storeri_ur, IntRegs, i32, store>;
1389defm : T_StoreAbsReg_Pats <S4_storerb_ur, IntRegs, i32, truncstorei8>;
1390defm : T_StoreAbsReg_Pats <S4_storerh_ur, IntRegs, i32, truncstorei16>;
1391
1392class Storexs_pat<PatFrag Store, PatFrag Value, InstHexagon MI>
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001393 : Pat<(Store Value:$Ru, (add I32:$Rs,
1394 (i32 (shl I32:$Rt, u2_0ImmPred:$u2)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001395 (MI IntRegs:$Rs, IntRegs:$Rt, imm:$u2, Value:$Ru)>;
1396
1397let AddedComplexity = 40 in {
1398 def: Storexs_pat<truncstorei8, I32, S4_storerb_rr>;
1399 def: Storexs_pat<truncstorei16, I32, S4_storerh_rr>;
1400 def: Storexs_pat<store, I32, S4_storeri_rr>;
1401 def: Storexs_pat<store, I64, S4_storerd_rr>;
1402}
1403
1404def s30_2ProperPred : PatLeaf<(i32 imm), [{
1405 int64_t v = (int64_t)N->getSExtValue();
1406 return isShiftedInt<30,2>(v) && !isShiftedInt<29,3>(v);
1407}]>;
1408def RoundTo8 : SDNodeXForm<imm, [{
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00001409 int32_t Imm = N->getSExtValue();
1410 return CurDAG->getTargetConstant(Imm & -8, SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001411}]>;
1412
1413let AddedComplexity = 40 in
1414def: Pat<(store I64:$Ru, (add I32:$Rs, s30_2ProperPred:$Off)),
1415 (S2_storerd_io (A2_addi I32:$Rs, 4), (RoundTo8 $Off), I64:$Ru)>;
1416
1417class Store_rr_pat<PatFrag Store, PatFrag Value, InstHexagon MI>
1418 : Pat<(Store Value:$Ru, (add I32:$Rs, I32:$Rt)),
1419 (MI IntRegs:$Rs, IntRegs:$Rt, 0, Value:$Ru)>;
1420
1421let AddedComplexity = 20 in {
1422 def: Store_rr_pat<truncstorei8, I32, S4_storerb_rr>;
1423 def: Store_rr_pat<truncstorei16, I32, S4_storerh_rr>;
1424 def: Store_rr_pat<store, I32, S4_storeri_rr>;
1425 def: Store_rr_pat<store, I64, S4_storerd_rr>;
1426}
1427
1428
1429def IMM_BYTE : SDNodeXForm<imm, [{
1430 // -1 etc is represented as 255 etc
1431 // assigning to a byte restores our desired signed value.
1432 int8_t imm = N->getSExtValue();
1433 return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32);
1434}]>;
1435
1436def IMM_HALF : SDNodeXForm<imm, [{
1437 // -1 etc is represented as 65535 etc
1438 // assigning to a short restores our desired signed value.
1439 int16_t imm = N->getSExtValue();
1440 return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32);
1441}]>;
1442
1443def IMM_WORD : SDNodeXForm<imm, [{
1444 // -1 etc can be represented as 4294967295 etc
1445 // Currently, it's not doing this. But some optimization
1446 // might convert -1 to a large +ve number.
1447 // assigning to a word restores our desired signed value.
1448 int32_t imm = N->getSExtValue();
1449 return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32);
1450}]>;
1451
1452def ToImmByte : OutPatFrag<(ops node:$R), (IMM_BYTE $R)>;
1453def ToImmHalf : OutPatFrag<(ops node:$R), (IMM_HALF $R)>;
1454def ToImmWord : OutPatFrag<(ops node:$R), (IMM_WORD $R)>;
1455
1456// Emit store-immediate, but only when the stored value will not be constant-
1457// extended. The reason for that is that there is no pass that can optimize
1458// constant extenders in store-immediate instructions. In some cases we can
1459// end up will a number of such stores, all of which store the same extended
1460// value (e.g. after unrolling a loop that initializes floating point array).
1461
1462// Predicates to determine if the 16-bit immediate is expressible as a sign-
1463// extended 8-bit immediate. Store-immediate-halfword will ignore any bits
1464// beyond 0..15, so we don't care what is in there.
1465
1466def i16in8ImmPred: PatLeaf<(i32 imm), [{
1467 int64_t v = (int16_t)N->getSExtValue();
1468 return v == (int64_t)(int8_t)v;
1469}]>;
1470
1471// Predicates to determine if the 32-bit immediate is expressible as a sign-
1472// extended 8-bit immediate.
1473def i32in8ImmPred: PatLeaf<(i32 imm), [{
1474 int64_t v = (int32_t)N->getSExtValue();
1475 return v == (int64_t)(int8_t)v;
1476}]>;
1477
Krzysztof Parzyszekb3a8d202017-06-13 17:10:16 +00001478class SmallStackStore<PatFrag Store>
1479 : PatFrag<(ops node:$Val, node:$Addr), (Store node:$Val, node:$Addr), [{
1480 return isSmallStackStore(cast<StoreSDNode>(N));
1481}]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001482
1483let AddedComplexity = 40 in {
1484 // Even though the offset is not extendable in the store-immediate, we
1485 // can still generate the fi# in the base address. If the final offset
1486 // is not valid for the instruction, we will replace it with a scratch
1487 // register.
Krzysztof Parzyszekb3a8d202017-06-13 17:10:16 +00001488 def: Storexm_fi_pat <SmallStackStore<truncstorei8>, s32_0ImmPred,
1489 ToImmByte, S4_storeirb_io>;
1490 def: Storexm_fi_pat <SmallStackStore<truncstorei16>, i16in8ImmPred,
1491 ToImmHalf, S4_storeirh_io>;
1492 def: Storexm_fi_pat <SmallStackStore<store>, i32in8ImmPred,
1493 ToImmWord, S4_storeiri_io>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001494
1495// defm: Storexm_fi_add_pat <truncstorei8, s32_0ImmPred, u6_0ImmPred, ToImmByte,
1496// S4_storeirb_io>;
1497// defm: Storexm_fi_add_pat <truncstorei16, i16in8ImmPred, u6_1ImmPred,
1498// ToImmHalf, S4_storeirh_io>;
1499// defm: Storexm_fi_add_pat <store, i32in8ImmPred, u6_2ImmPred, ToImmWord,
1500// S4_storeiri_io>;
1501
1502 defm: Storexm_add_pat<truncstorei8, s32_0ImmPred, u6_0ImmPred, ToImmByte,
1503 S4_storeirb_io>;
1504 defm: Storexm_add_pat<truncstorei16, i16in8ImmPred, u6_1ImmPred, ToImmHalf,
1505 S4_storeirh_io>;
1506 defm: Storexm_add_pat<store, i32in8ImmPred, u6_2ImmPred, ToImmWord,
1507 S4_storeiri_io>;
1508}
1509
1510def: Storexm_simple_pat<truncstorei8, s32_0ImmPred, ToImmByte, S4_storeirb_io>;
1511def: Storexm_simple_pat<truncstorei16, s32_0ImmPred, ToImmHalf, S4_storeirh_io>;
1512def: Storexm_simple_pat<store, s32_0ImmPred, ToImmWord, S4_storeiri_io>;
1513
1514// op(Ps, op(Pt, Pu))
1515class LogLog_pat<SDNode Op1, SDNode Op2, InstHexagon MI>
1516 : Pat<(i1 (Op1 I1:$Ps, (Op2 I1:$Pt, I1:$Pu))),
1517 (MI I1:$Ps, I1:$Pt, I1:$Pu)>;
1518
1519// op(Ps, op(Pt, ~Pu))
1520class LogLogNot_pat<SDNode Op1, SDNode Op2, InstHexagon MI>
1521 : Pat<(i1 (Op1 I1:$Ps, (Op2 I1:$Pt, (not I1:$Pu)))),
1522 (MI I1:$Ps, I1:$Pt, I1:$Pu)>;
1523
1524def: LogLog_pat<and, and, C4_and_and>;
1525def: LogLog_pat<and, or, C4_and_or>;
1526def: LogLog_pat<or, and, C4_or_and>;
1527def: LogLog_pat<or, or, C4_or_or>;
1528
1529def: LogLogNot_pat<and, and, C4_and_andn>;
1530def: LogLogNot_pat<and, or, C4_and_orn>;
1531def: LogLogNot_pat<or, and, C4_or_andn>;
1532def: LogLogNot_pat<or, or, C4_or_orn>;
1533
1534//===----------------------------------------------------------------------===//
1535// PIC: Support for PIC compilations. The patterns and SD nodes defined
1536// below are needed to support code generation for PIC
1537//===----------------------------------------------------------------------===//
1538
1539def SDT_HexagonAtGot
1540 : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i32>]>;
1541def SDT_HexagonAtPcrel
1542 : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
1543
1544// AT_GOT address-of-GOT, address-of-global, offset-in-global
1545def HexagonAtGot : SDNode<"HexagonISD::AT_GOT", SDT_HexagonAtGot>;
1546// AT_PCREL address-of-global
1547def HexagonAtPcrel : SDNode<"HexagonISD::AT_PCREL", SDT_HexagonAtPcrel>;
1548
1549def: Pat<(HexagonAtGot I32:$got, I32:$addr, (i32 0)),
1550 (L2_loadri_io I32:$got, imm:$addr)>;
1551def: Pat<(HexagonAtGot I32:$got, I32:$addr, s30_2ImmPred:$off),
1552 (A2_addi (L2_loadri_io I32:$got, imm:$addr), imm:$off)>;
1553def: Pat<(HexagonAtPcrel I32:$addr),
1554 (C4_addipc imm:$addr)>;
1555
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001556def: Pat<(i64 (and I64:$Rs, (i64 (not I64:$Rt)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001557 (A4_andnp DoubleRegs:$Rs, DoubleRegs:$Rt)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001558def: Pat<(i64 (or I64:$Rs, (i64 (not I64:$Rt)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001559 (A4_ornp DoubleRegs:$Rs, DoubleRegs:$Rt)>;
1560
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001561def: Pat<(add I32:$Rs, (add I32:$Ru, s32_0ImmPred:$s6)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001562 (S4_addaddi IntRegs:$Rs, IntRegs:$Ru, imm:$s6)>;
1563
1564// Rd=add(Rs,sub(#s6,Ru))
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001565def: Pat<(add I32:$src1, (sub s32_0ImmPred:$src2,
1566 I32:$src3)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001567 (S4_subaddi IntRegs:$src1, s32_0ImmPred:$src2, IntRegs:$src3)>;
1568
1569// Rd=sub(add(Rs,#s6),Ru)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001570def: Pat<(sub (add I32:$src1, s32_0ImmPred:$src2),
1571 I32:$src3),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001572 (S4_subaddi IntRegs:$src1, s32_0ImmPred:$src2, IntRegs:$src3)>;
1573
1574// Rd=add(sub(Rs,Ru),#s6)
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001575def: Pat<(add (sub I32:$src1, I32:$src3),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001576 (s32_0ImmPred:$src2)),
1577 (S4_subaddi IntRegs:$src1, s32_0ImmPred:$src2, IntRegs:$src3)>;
1578
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001579def: Pat<(xor I64:$dst2,
1580 (xor I64:$Rss, I64:$Rtt)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001581 (M4_xor_xacc DoubleRegs:$dst2, DoubleRegs:$Rss, DoubleRegs:$Rtt)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001582def: Pat<(or I32:$Ru, (and (i32 IntRegs:$_src_), s32_0ImmPred:$s10)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001583 (S4_or_andix IntRegs:$Ru, IntRegs:$_src_, imm:$s10)>;
1584
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001585def: Pat<(or I32:$src1, (and I32:$Rs, s32_0ImmPred:$s10)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001586 (S4_or_andi IntRegs:$src1, IntRegs:$Rs, imm:$s10)>;
1587
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001588def: Pat<(or I32:$src1, (or I32:$Rs, s32_0ImmPred:$s10)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001589 (S4_or_ori IntRegs:$src1, IntRegs:$Rs, imm:$s10)>;
1590
1591
1592
1593// Count trailing zeros: 64-bit.
1594def: Pat<(i32 (trunc (cttz I64:$Rss))), (S2_ct0p I64:$Rss)>;
1595
1596// Count trailing ones: 64-bit.
1597def: Pat<(i32 (trunc (cttz (not I64:$Rss)))), (S2_ct1p I64:$Rss)>;
1598
1599// Define leading/trailing patterns that require zero-extensions to 64 bits.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001600def: Pat<(i64 (ctlz I64:$Rss)), (ToZext64 (S2_cl0p I64:$Rss))>;
1601def: Pat<(i64 (cttz I64:$Rss)), (ToZext64 (S2_ct0p I64:$Rss))>;
1602def: Pat<(i64 (ctlz (not I64:$Rss))), (ToZext64 (S2_cl1p I64:$Rss))>;
1603def: Pat<(i64 (cttz (not I64:$Rss))), (ToZext64 (S2_ct1p I64:$Rss))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001604
Krzysztof Parzyszekaf5ff652017-02-23 15:02:09 +00001605def: Pat<(i64 (ctpop I64:$Rss)), (ToZext64 (S5_popcountp I64:$Rss))>;
1606def: Pat<(i32 (ctpop I32:$Rs)), (S5_popcountp (A4_combineir 0, I32:$Rs))>;
1607
1608def: Pat<(bitreverse I32:$Rs), (S2_brev I32:$Rs)>;
1609def: Pat<(bitreverse I64:$Rss), (S2_brevp I64:$Rss)>;
1610
1611def: Pat<(bswap I32:$Rs), (A2_swiz I32:$Rs)>;
1612def: Pat<(bswap I64:$Rss), (A2_combinew (A2_swiz (LoReg $Rss)),
1613 (A2_swiz (HiReg $Rss)))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001614
1615let AddedComplexity = 20 in { // Complexity greater than cmp reg-imm.
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001616 def: Pat<(i1 (seteq (and (shl 1, u5_0ImmPred:$u5), I32:$Rs), 0)),
1617 (S4_ntstbit_i I32:$Rs, u5_0ImmPred:$u5)>;
1618 def: Pat<(i1 (seteq (and (shl 1, I32:$Rt), I32:$Rs), 0)),
1619 (S4_ntstbit_r I32:$Rs, I32:$Rt)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001620}
1621
1622// Add extra complexity to prefer these instructions over bitsset/bitsclr.
1623// The reason is that tstbit/ntstbit can be folded into a compound instruction:
1624// if ([!]tstbit(...)) jump ...
1625let AddedComplexity = 100 in
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001626def: Pat<(i1 (setne (and I32:$Rs, (i32 IsPow2_32:$u5)), (i32 0))),
1627 (S2_tstbit_i I32:$Rs, (Log2_32 imm:$u5))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001628
1629let AddedComplexity = 100 in
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001630def: Pat<(i1 (seteq (and I32:$Rs, (i32 IsPow2_32:$u5)), (i32 0))),
1631 (S4_ntstbit_i I32:$Rs, (Log2_32 imm:$u5))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001632
1633// Do not increase complexity of these patterns. In the DAG, "cmp i8" may be
1634// represented as a compare against "value & 0xFF", which is an exact match
1635// for cmpb (same for cmph). The patterns below do not contain any additional
1636// complexity that would make them preferable, and if they were actually used
1637// instead of cmpb/cmph, they would result in a compare against register that
1638// is loaded with the byte/half mask (i.e. 0xFF or 0xFFFF).
1639def: Pat<(i1 (setne (and I32:$Rs, u6_0ImmPred:$u6), 0)),
1640 (C4_nbitsclri I32:$Rs, u6_0ImmPred:$u6)>;
1641def: Pat<(i1 (setne (and I32:$Rs, I32:$Rt), 0)),
1642 (C4_nbitsclr I32:$Rs, I32:$Rt)>;
1643def: Pat<(i1 (setne (and I32:$Rs, I32:$Rt), I32:$Rt)),
1644 (C4_nbitsset I32:$Rs, I32:$Rt)>;
1645
1646
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001647def: Pat<(add (mul I32:$Rs, u6_0ImmPred:$U6), u32_0ImmPred:$u6),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001648 (M4_mpyri_addi imm:$u6, IntRegs:$Rs, imm:$U6)>;
Krzysztof Parzyszek7aca2fd2017-06-09 15:26:21 +00001649def: Pat<(add (mul I32:$Rs, u6_0ImmPred:$U6),
1650 (HexagonCONST32 tglobaladdr:$global)),
1651 (M4_mpyri_addi tglobaladdr:$global, IntRegs:$Rs, imm:$U6)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001652def: Pat<(add (mul I32:$Rs, I32:$Rt), u32_0ImmPred:$u6),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001653 (M4_mpyrr_addi imm:$u6, IntRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszek7aca2fd2017-06-09 15:26:21 +00001654def: Pat<(add (mul I32:$Rs, I32:$Rt),
1655 (HexagonCONST32 tglobaladdr:$global)),
1656 (M4_mpyrr_addi tglobaladdr:$global, IntRegs:$Rs, IntRegs:$Rt)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001657def: Pat<(add I32:$src1, (mul I32:$src3, u6_2ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001658 (M4_mpyri_addr_u2 IntRegs:$src1, imm:$src2, IntRegs:$src3)>;
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001659def: Pat<(add I32:$src1, (mul I32:$src3, u32_0ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001660 (M4_mpyri_addr IntRegs:$src1, IntRegs:$src3, imm:$src2)>;
1661
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001662def: Pat<(add I32:$Ru, (mul (i32 IntRegs:$_src_), I32:$Rs)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001663 (M4_mpyrr_addr IntRegs:$Ru, IntRegs:$_src_, IntRegs:$Rs)>;
1664
1665def: T_vcmp_pat<A4_vcmpbgt, setgt, v8i8>;
1666
1667class T_Shift_CommOp_pat<InstHexagon MI, SDNode Op, SDNode ShOp>
1668 : Pat<(Op (ShOp IntRegs:$Rx, u5_0ImmPred:$U5), u32_0ImmPred:$u8),
1669 (MI u32_0ImmPred:$u8, IntRegs:$Rx, u5_0ImmPred:$U5)>;
1670
1671let AddedComplexity = 200 in {
1672 def : T_Shift_CommOp_pat <S4_addi_asl_ri, add, shl>;
1673 def : T_Shift_CommOp_pat <S4_addi_lsr_ri, add, srl>;
1674 def : T_Shift_CommOp_pat <S4_andi_asl_ri, and, shl>;
1675 def : T_Shift_CommOp_pat <S4_andi_lsr_ri, and, srl>;
1676}
1677
1678let AddedComplexity = 30 in {
1679 def : T_Shift_CommOp_pat <S4_ori_asl_ri, or, shl>;
1680 def : T_Shift_CommOp_pat <S4_ori_lsr_ri, or, srl>;
1681}
1682
1683class T_Shift_Op_pat<InstHexagon MI, SDNode Op, SDNode ShOp>
1684 : Pat<(Op u32_0ImmPred:$u8, (ShOp IntRegs:$Rx, u5_0ImmPred:$U5)),
1685 (MI u32_0ImmPred:$u8, IntRegs:$Rx, u5_0ImmPred:$U5)>;
1686
1687def : T_Shift_Op_pat <S4_subi_asl_ri, sub, shl>;
1688def : T_Shift_Op_pat <S4_subi_lsr_ri, sub, srl>;
1689
1690let AddedComplexity = 200 in {
1691 def: Pat<(add addrga:$addr, (shl I32:$src2, u5_0ImmPred:$src3)),
1692 (S4_addi_asl_ri addrga:$addr, IntRegs:$src2, u5_0ImmPred:$src3)>;
1693 def: Pat<(add addrga:$addr, (srl I32:$src2, u5_0ImmPred:$src3)),
1694 (S4_addi_lsr_ri addrga:$addr, IntRegs:$src2, u5_0ImmPred:$src3)>;
1695 def: Pat<(sub addrga:$addr, (shl I32:$src2, u5_0ImmPred:$src3)),
1696 (S4_subi_asl_ri addrga:$addr, IntRegs:$src2, u5_0ImmPred:$src3)>;
1697 def: Pat<(sub addrga:$addr, (srl I32:$src2, u5_0ImmPred:$src3)),
1698 (S4_subi_lsr_ri addrga:$addr, IntRegs:$src2, u5_0ImmPred:$src3)>;
1699}
1700
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00001701def: Pat<(shl s6_0ImmPred:$s6, I32:$Rt),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001702 (S4_lsli imm:$s6, IntRegs:$Rt)>;
1703
1704
1705//===----------------------------------------------------------------------===//
1706// MEMOP
1707//===----------------------------------------------------------------------===//
1708
1709def m5_0Imm8Pred : PatLeaf<(i32 imm), [{
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00001710 int8_t V = N->getSExtValue();
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001711 return -32 < V && V <= -1;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001712}]>;
1713
1714def m5_0Imm16Pred : PatLeaf<(i32 imm), [{
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00001715 int16_t V = N->getSExtValue();
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001716 return -32 < V && V <= -1;
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00001717}]>;
1718
1719def m5_0ImmPred : PatLeaf<(i32 imm), [{
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001720 int64_t V = N->getSExtValue();
1721 return -31 <= V && V <= -1;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001722}]>;
1723
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001724def IsNPow2_8 : PatLeaf<(i32 imm), [{
1725 uint8_t NV = ~N->getZExtValue();
1726 return isPowerOf2_32(NV);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001727}]>;
1728
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001729def IsNPow2_16 : PatLeaf<(i32 imm), [{
1730 uint16_t NV = ~N->getZExtValue();
1731 return isPowerOf2_32(NV);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001732}]>;
1733
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001734def Log2_8 : SDNodeXForm<imm, [{
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00001735 uint8_t V = N->getZExtValue();
1736 return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001737}]>;
1738
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001739def Log2_16 : SDNodeXForm<imm, [{
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00001740 uint16_t V = N->getZExtValue();
1741 return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001742}]>;
1743
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001744def LogN2_8 : SDNodeXForm<imm, [{
1745 uint8_t NV = ~N->getZExtValue();
1746 return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001747}]>;
1748
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001749def LogN2_16 : SDNodeXForm<imm, [{
1750 uint16_t NV = ~N->getZExtValue();
1751 return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001752}]>;
1753
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001754def NegImm8 : SDNodeXForm<imm, [{
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001755 int8_t NV = -N->getSExtValue();
1756 return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001757}]>;
1758
1759def NegImm16 : SDNodeXForm<imm, [{
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001760 int16_t NV = -N->getSExtValue();
1761 return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001762}]>;
1763
1764def NegImm32 : SDNodeXForm<imm, [{
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001765 int32_t NV = -N->getSExtValue();
1766 return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32);
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001767}]>;
1768
1769def IdImm : SDNodeXForm<imm, [{ return SDValue(N, 0); }]>;
1770
1771multiclass Memopxr_simple_pat<PatFrag Load, PatFrag Store, SDNode Oper,
1772 InstHexagon MI> {
1773 // Addr: i32
1774 def: Pat<(Store (Oper (Load I32:$Rs), I32:$A), I32:$Rs),
1775 (MI I32:$Rs, 0, I32:$A)>;
1776 // Addr: fi
1777 def: Pat<(Store (Oper (Load AddrFI:$Rs), I32:$A), AddrFI:$Rs),
1778 (MI AddrFI:$Rs, 0, I32:$A)>;
1779}
1780
1781multiclass Memopxr_add_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred,
1782 SDNode Oper, InstHexagon MI> {
1783 // Addr: i32
1784 def: Pat<(Store (Oper (Load (add I32:$Rs, ImmPred:$Off)), I32:$A),
1785 (add I32:$Rs, ImmPred:$Off)),
1786 (MI I32:$Rs, imm:$Off, I32:$A)>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +00001787 def: Pat<(Store (Oper (Load (IsOrAdd I32:$Rs, ImmPred:$Off)), I32:$A),
1788 (IsOrAdd I32:$Rs, ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001789 (MI I32:$Rs, imm:$Off, I32:$A)>;
1790 // Addr: fi
1791 def: Pat<(Store (Oper (Load (add AddrFI:$Rs, ImmPred:$Off)), I32:$A),
1792 (add AddrFI:$Rs, ImmPred:$Off)),
1793 (MI AddrFI:$Rs, imm:$Off, I32:$A)>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +00001794 def: Pat<(Store (Oper (Load (IsOrAdd AddrFI:$Rs, ImmPred:$Off)), I32:$A),
1795 (IsOrAdd AddrFI:$Rs, ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001796 (MI AddrFI:$Rs, imm:$Off, I32:$A)>;
1797}
1798
1799multiclass Memopxr_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred,
1800 SDNode Oper, InstHexagon MI> {
1801 defm: Memopxr_simple_pat <Load, Store, Oper, MI>;
1802 defm: Memopxr_add_pat <Load, Store, ImmPred, Oper, MI>;
1803}
1804
1805let AddedComplexity = 180 in {
1806 // add reg
1807 defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, add,
1808 /*anyext*/ L4_add_memopb_io>;
1809 defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, add,
1810 /*sext*/ L4_add_memopb_io>;
1811 defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, add,
1812 /*zext*/ L4_add_memopb_io>;
1813 defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, add,
1814 /*anyext*/ L4_add_memoph_io>;
1815 defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, add,
1816 /*sext*/ L4_add_memoph_io>;
1817 defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, add,
1818 /*zext*/ L4_add_memoph_io>;
1819 defm: Memopxr_pat<load, store, u6_2ImmPred, add, L4_add_memopw_io>;
1820
1821 // sub reg
1822 defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, sub,
1823 /*anyext*/ L4_sub_memopb_io>;
1824 defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub,
1825 /*sext*/ L4_sub_memopb_io>;
1826 defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub,
1827 /*zext*/ L4_sub_memopb_io>;
1828 defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, sub,
1829 /*anyext*/ L4_sub_memoph_io>;
1830 defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub,
1831 /*sext*/ L4_sub_memoph_io>;
1832 defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub,
1833 /*zext*/ L4_sub_memoph_io>;
1834 defm: Memopxr_pat<load, store, u6_2ImmPred, sub, L4_sub_memopw_io>;
1835
1836 // and reg
1837 defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, and,
1838 /*anyext*/ L4_and_memopb_io>;
1839 defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, and,
1840 /*sext*/ L4_and_memopb_io>;
1841 defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, and,
1842 /*zext*/ L4_and_memopb_io>;
1843 defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, and,
1844 /*anyext*/ L4_and_memoph_io>;
1845 defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, and,
1846 /*sext*/ L4_and_memoph_io>;
1847 defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, and,
1848 /*zext*/ L4_and_memoph_io>;
1849 defm: Memopxr_pat<load, store, u6_2ImmPred, and, L4_and_memopw_io>;
1850
1851 // or reg
1852 defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, or,
1853 /*anyext*/ L4_or_memopb_io>;
1854 defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, or,
1855 /*sext*/ L4_or_memopb_io>;
1856 defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, or,
1857 /*zext*/ L4_or_memopb_io>;
1858 defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, or,
1859 /*anyext*/ L4_or_memoph_io>;
1860 defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, or,
1861 /*sext*/ L4_or_memoph_io>;
1862 defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, or,
1863 /*zext*/ L4_or_memoph_io>;
1864 defm: Memopxr_pat<load, store, u6_2ImmPred, or, L4_or_memopw_io>;
1865}
1866
1867
1868multiclass Memopxi_simple_pat<PatFrag Load, PatFrag Store, SDNode Oper,
1869 PatFrag Arg, SDNodeXForm ArgMod,
1870 InstHexagon MI> {
1871 // Addr: i32
1872 def: Pat<(Store (Oper (Load I32:$Rs), Arg:$A), I32:$Rs),
1873 (MI I32:$Rs, 0, (ArgMod Arg:$A))>;
1874 // Addr: fi
1875 def: Pat<(Store (Oper (Load AddrFI:$Rs), Arg:$A), AddrFI:$Rs),
1876 (MI AddrFI:$Rs, 0, (ArgMod Arg:$A))>;
1877}
1878
1879multiclass Memopxi_add_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred,
1880 SDNode Oper, PatFrag Arg, SDNodeXForm ArgMod,
1881 InstHexagon MI> {
1882 // Addr: i32
1883 def: Pat<(Store (Oper (Load (add I32:$Rs, ImmPred:$Off)), Arg:$A),
1884 (add I32:$Rs, ImmPred:$Off)),
1885 (MI I32:$Rs, imm:$Off, (ArgMod Arg:$A))>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +00001886 def: Pat<(Store (Oper (Load (IsOrAdd I32:$Rs, ImmPred:$Off)), Arg:$A),
1887 (IsOrAdd I32:$Rs, ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001888 (MI I32:$Rs, imm:$Off, (ArgMod Arg:$A))>;
1889 // Addr: fi
1890 def: Pat<(Store (Oper (Load (add AddrFI:$Rs, ImmPred:$Off)), Arg:$A),
1891 (add AddrFI:$Rs, ImmPred:$Off)),
1892 (MI AddrFI:$Rs, imm:$Off, (ArgMod Arg:$A))>;
Krzysztof Parzyszekb16a4e52016-11-14 20:53:09 +00001893 def: Pat<(Store (Oper (Load (IsOrAdd AddrFI:$Rs, ImmPred:$Off)), Arg:$A),
1894 (IsOrAdd AddrFI:$Rs, ImmPred:$Off)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001895 (MI AddrFI:$Rs, imm:$Off, (ArgMod Arg:$A))>;
1896}
1897
1898multiclass Memopxi_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred,
1899 SDNode Oper, PatFrag Arg, SDNodeXForm ArgMod,
1900 InstHexagon MI> {
1901 defm: Memopxi_simple_pat <Load, Store, Oper, Arg, ArgMod, MI>;
1902 defm: Memopxi_add_pat <Load, Store, ImmPred, Oper, Arg, ArgMod, MI>;
1903}
1904
1905
1906let AddedComplexity = 200 in {
1907 // add imm
1908 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, add, u5_0ImmPred,
1909 /*anyext*/ IdImm, L4_iadd_memopb_io>;
1910 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, add, u5_0ImmPred,
1911 /*sext*/ IdImm, L4_iadd_memopb_io>;
1912 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, add, u5_0ImmPred,
1913 /*zext*/ IdImm, L4_iadd_memopb_io>;
1914 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5_0ImmPred,
1915 /*anyext*/ IdImm, L4_iadd_memoph_io>;
1916 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5_0ImmPred,
1917 /*sext*/ IdImm, L4_iadd_memoph_io>;
1918 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5_0ImmPred,
1919 /*zext*/ IdImm, L4_iadd_memoph_io>;
1920 defm: Memopxi_pat<load, store, u6_2ImmPred, add, u5_0ImmPred, IdImm,
1921 L4_iadd_memopw_io>;
1922 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, sub, m5_0Imm8Pred,
1923 /*anyext*/ NegImm8, L4_iadd_memopb_io>;
1924 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub, m5_0Imm8Pred,
1925 /*sext*/ NegImm8, L4_iadd_memopb_io>;
1926 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub, m5_0Imm8Pred,
1927 /*zext*/ NegImm8, L4_iadd_memopb_io>;
1928 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, sub, m5_0Imm16Pred,
1929 /*anyext*/ NegImm16, L4_iadd_memoph_io>;
1930 defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub, m5_0Imm16Pred,
1931 /*sext*/ NegImm16, L4_iadd_memoph_io>;
1932 defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub, m5_0Imm16Pred,
1933 /*zext*/ NegImm16, L4_iadd_memoph_io>;
1934 defm: Memopxi_pat<load, store, u6_2ImmPred, sub, m5_0ImmPred, NegImm32,
1935 L4_iadd_memopw_io>;
1936
1937 // sub imm
1938 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, sub, u5_0ImmPred,
1939 /*anyext*/ IdImm, L4_isub_memopb_io>;
1940 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub, u5_0ImmPred,
1941 /*sext*/ IdImm, L4_isub_memopb_io>;
1942 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub, u5_0ImmPred,
1943 /*zext*/ IdImm, L4_isub_memopb_io>;
1944 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, sub, u5_0ImmPred,
1945 /*anyext*/ IdImm, L4_isub_memoph_io>;
1946 defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub, u5_0ImmPred,
1947 /*sext*/ IdImm, L4_isub_memoph_io>;
1948 defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub, u5_0ImmPred,
1949 /*zext*/ IdImm, L4_isub_memoph_io>;
1950 defm: Memopxi_pat<load, store, u6_2ImmPred, sub, u5_0ImmPred, IdImm,
1951 L4_isub_memopw_io>;
1952 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, add, m5_0Imm8Pred,
1953 /*anyext*/ NegImm8, L4_isub_memopb_io>;
1954 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, add, m5_0Imm8Pred,
1955 /*sext*/ NegImm8, L4_isub_memopb_io>;
1956 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, add, m5_0Imm8Pred,
1957 /*zext*/ NegImm8, L4_isub_memopb_io>;
1958 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, m5_0Imm16Pred,
1959 /*anyext*/ NegImm16, L4_isub_memoph_io>;
1960 defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, add, m5_0Imm16Pred,
1961 /*sext*/ NegImm16, L4_isub_memoph_io>;
1962 defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, add, m5_0Imm16Pred,
1963 /*zext*/ NegImm16, L4_isub_memoph_io>;
1964 defm: Memopxi_pat<load, store, u6_2ImmPred, add, m5_0ImmPred, NegImm32,
1965 L4_isub_memopw_io>;
1966
1967 // clrbit imm
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001968 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, and, IsNPow2_8,
1969 /*anyext*/ LogN2_8, L4_iand_memopb_io>;
1970 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, and, IsNPow2_8,
1971 /*sext*/ LogN2_8, L4_iand_memopb_io>;
1972 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, and, IsNPow2_8,
1973 /*zext*/ LogN2_8, L4_iand_memopb_io>;
1974 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, and, IsNPow2_16,
1975 /*anyext*/ LogN2_16, L4_iand_memoph_io>;
1976 defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, and, IsNPow2_16,
1977 /*sext*/ LogN2_16, L4_iand_memoph_io>;
1978 defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, and, IsNPow2_16,
1979 /*zext*/ LogN2_16, L4_iand_memoph_io>;
1980 defm: Memopxi_pat<load, store, u6_2ImmPred, and, IsNPow2_32,
1981 LogN2_32, L4_iand_memopw_io>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001982
1983 // setbit imm
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00001984 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, or, IsPow2_32,
1985 /*anyext*/ Log2_8, L4_ior_memopb_io>;
1986 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, or, IsPow2_32,
1987 /*sext*/ Log2_8, L4_ior_memopb_io>;
1988 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, or, IsPow2_32,
1989 /*zext*/ Log2_8, L4_ior_memopb_io>;
1990 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, or, IsPow2_32,
1991 /*anyext*/ Log2_16, L4_ior_memoph_io>;
1992 defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, or, IsPow2_32,
1993 /*sext*/ Log2_16, L4_ior_memoph_io>;
1994 defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, or, IsPow2_32,
1995 /*zext*/ Log2_16, L4_ior_memoph_io>;
1996 defm: Memopxi_pat<load, store, u6_2ImmPred, or, IsPow2_32,
1997 Log2_32, L4_ior_memopw_io>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00001998}
1999
2000def : T_CMP_pat <C4_cmpneqi, setne, s32_0ImmPred>;
2001def : T_CMP_pat <C4_cmpltei, setle, s32_0ImmPred>;
2002def : T_CMP_pat <C4_cmplteui, setule, u9_0ImmPred>;
2003
2004// Map cmplt(Rs, Imm) -> !cmpgt(Rs, Imm-1).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00002005def: Pat<(i1 (setlt I32:$src1, s32_0ImmPred:$src2)),
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00002006 (C4_cmpltei IntRegs:$src1, (SDEC1 s32_0ImmPred:$src2))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002007
2008// rs != rt -> !(rs == rt).
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00002009def: Pat<(i1 (setne I32:$src1, s32_0ImmPred:$src2)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002010 (C4_cmpneqi IntRegs:$src1, s32_0ImmPred:$src2)>;
2011
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002012// For the sequence
2013// zext( setult ( and(Rs, 255), u8))
2014// Use the isdigit transformation below
2015
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00002016
2017def u7_0PosImmPred : ImmLeaf<i32, [{
2018 // True if the immediate fits in an 7-bit unsigned field and
2019 // is strictly greater than 0.
2020 return Imm > 0 && isUInt<7>(Imm);
2021}]>;
2022
2023
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002024// Generate code of the form 'C2_muxii(cmpbgtui(Rdd, C-1),0,1)'
2025// for C code of the form r = ((c>='0') & (c<='9')) ? 1 : 0;.
2026// The isdigit transformation relies on two 'clever' aspects:
2027// 1) The data type is unsigned which allows us to eliminate a zero test after
2028// biasing the expression by 48. We are depending on the representation of
2029// the unsigned types, and semantics.
2030// 2) The front end has converted <= 9 into < 10 on entry to LLVM
2031//
2032// For the C code:
2033// retval = ((c>='0') & (c<='9')) ? 1 : 0;
2034// The code is transformed upstream of llvm into
2035// retval = (c-48) < 10 ? 1 : 0;
Krzysztof Parzyszek846597d2016-11-06 18:05:14 +00002036
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002037let AddedComplexity = 139 in
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +00002038def: Pat<(i32 (zext (i1 (setult (and I32:$src1, 255), u7_0PosImmPred:$src2)))),
Krzysztof Parzyszekf9142782016-11-06 18:09:56 +00002039 (C2_muxii (A4_cmpbgtui IntRegs:$src1, (UDEC1 imm:$src2)), 0, 1)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002040
2041class Loada_pat<PatFrag Load, ValueType VT, PatFrag Addr, InstHexagon MI>
2042 : Pat<(VT (Load Addr:$addr)), (MI Addr:$addr)>;
2043
2044class Loadam_pat<PatFrag Load, ValueType VT, PatFrag Addr, PatFrag ValueMod,
2045 InstHexagon MI>
2046 : Pat<(VT (Load Addr:$addr)), (ValueMod (MI Addr:$addr))>;
2047
2048class Storea_pat<PatFrag Store, PatFrag Value, PatFrag Addr, InstHexagon MI>
2049 : Pat<(Store Value:$val, Addr:$addr), (MI Addr:$addr, Value:$val)>;
2050
2051class Stoream_pat<PatFrag Store, PatFrag Value, PatFrag Addr, PatFrag ValueMod,
2052 InstHexagon MI>
2053 : Pat<(Store Value:$val, Addr:$addr),
2054 (MI Addr:$addr, (ValueMod Value:$val))>;
2055
2056let AddedComplexity = 30 in {
2057 def: Storea_pat<truncstorei8, I32, addrga, PS_storerbabs>;
2058 def: Storea_pat<truncstorei16, I32, addrga, PS_storerhabs>;
2059 def: Storea_pat<store, I32, addrga, PS_storeriabs>;
2060 def: Storea_pat<store, I64, addrga, PS_storerdabs>;
2061
2062 def: Stoream_pat<truncstorei8, I64, addrga, LoReg, PS_storerbabs>;
2063 def: Stoream_pat<truncstorei16, I64, addrga, LoReg, PS_storerhabs>;
2064 def: Stoream_pat<truncstorei32, I64, addrga, LoReg, PS_storeriabs>;
2065}
2066
2067def: Storea_pat<SwapSt<atomic_store_8>, I32, addrgp, S2_storerbgp>;
2068def: Storea_pat<SwapSt<atomic_store_16>, I32, addrgp, S2_storerhgp>;
2069def: Storea_pat<SwapSt<atomic_store_32>, I32, addrgp, S2_storerigp>;
2070def: Storea_pat<SwapSt<atomic_store_64>, I64, addrgp, S2_storerdgp>;
2071
2072let AddedComplexity = 100 in {
2073 def: Storea_pat<truncstorei8, I32, addrgp, S2_storerbgp>;
2074 def: Storea_pat<truncstorei16, I32, addrgp, S2_storerhgp>;
2075 def: Storea_pat<store, I32, addrgp, S2_storerigp>;
2076 def: Storea_pat<store, I64, addrgp, S2_storerdgp>;
2077
2078 // Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
2079 // to "r0 = 1; memw(#foo) = r0"
2080 let AddedComplexity = 100 in
2081 def: Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
2082 (S2_storerbgp tglobaladdr:$global, (A2_tfrsi 1))>;
2083}
2084
2085class LoadAbs_pats <PatFrag ldOp, InstHexagon MI, ValueType VT = i32>
2086 : Pat <(VT (ldOp (HexagonCONST32 tglobaladdr:$absaddr))),
2087 (VT (MI tglobaladdr:$absaddr))>;
2088
2089let AddedComplexity = 30 in {
2090 def: LoadAbs_pats <load, PS_loadriabs>;
2091 def: LoadAbs_pats <zextloadi1, PS_loadrubabs>;
2092 def: LoadAbs_pats <sextloadi8, PS_loadrbabs>;
2093 def: LoadAbs_pats <extloadi8, PS_loadrubabs>;
2094 def: LoadAbs_pats <zextloadi8, PS_loadrubabs>;
2095 def: LoadAbs_pats <sextloadi16, PS_loadrhabs>;
2096 def: LoadAbs_pats <extloadi16, PS_loadruhabs>;
2097 def: LoadAbs_pats <zextloadi16, PS_loadruhabs>;
2098 def: LoadAbs_pats <load, PS_loadrdabs, i64>;
2099}
2100
2101let AddedComplexity = 30 in
2102def: Pat<(i64 (zextloadi1 (HexagonCONST32 tglobaladdr:$absaddr))),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00002103 (ToZext64 (PS_loadrubabs tglobaladdr:$absaddr))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002104
2105def: Loada_pat<atomic_load_8, i32, addrgp, L2_loadrubgp>;
2106def: Loada_pat<atomic_load_16, i32, addrgp, L2_loadruhgp>;
2107def: Loada_pat<atomic_load_32, i32, addrgp, L2_loadrigp>;
2108def: Loada_pat<atomic_load_64, i64, addrgp, L2_loadrdgp>;
2109
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002110def: Loadam_pat<load, i1, addrga, I32toI1, PS_loadrubabs>;
2111def: Loadam_pat<load, i1, addrgp, I32toI1, L2_loadrubgp>;
2112
2113def: Stoream_pat<store, I1, addrga, I1toI32, PS_storerbabs>;
2114def: Stoream_pat<store, I1, addrgp, I1toI32, S2_storerbgp>;
2115
2116// Map from load(globaladdress) -> mem[u][bhwd](#foo)
2117class LoadGP_pats <PatFrag ldOp, InstHexagon MI, ValueType VT = i32>
2118 : Pat <(VT (ldOp (HexagonCONST32_GP tglobaladdr:$global))),
2119 (VT (MI tglobaladdr:$global))>;
2120
2121let AddedComplexity = 100 in {
2122 def: LoadGP_pats <extloadi8, L2_loadrubgp>;
2123 def: LoadGP_pats <sextloadi8, L2_loadrbgp>;
2124 def: LoadGP_pats <zextloadi8, L2_loadrubgp>;
2125 def: LoadGP_pats <extloadi16, L2_loadruhgp>;
2126 def: LoadGP_pats <sextloadi16, L2_loadrhgp>;
2127 def: LoadGP_pats <zextloadi16, L2_loadruhgp>;
2128 def: LoadGP_pats <load, L2_loadrigp>;
2129 def: LoadGP_pats <load, L2_loadrdgp, i64>;
2130}
2131
2132// When the Interprocedural Global Variable optimizer realizes that a certain
2133// global variable takes only two constant values, it shrinks the global to
2134// a boolean. Catch those loads here in the following 3 patterns.
2135let AddedComplexity = 100 in {
2136 def: LoadGP_pats <extloadi1, L2_loadrubgp>;
2137 def: LoadGP_pats <zextloadi1, L2_loadrubgp>;
2138}
2139
2140// Transfer global address into a register
2141def: Pat<(HexagonCONST32 tglobaladdr:$Rs), (A2_tfrsi imm:$Rs)>;
2142def: Pat<(HexagonCONST32_GP tblockaddress:$Rs), (A2_tfrsi imm:$Rs)>;
2143def: Pat<(HexagonCONST32_GP tglobaladdr:$Rs), (A2_tfrsi imm:$Rs)>;
2144
2145let AddedComplexity = 30 in {
2146 def: Storea_pat<truncstorei8, I32, u32_0ImmPred, PS_storerbabs>;
2147 def: Storea_pat<truncstorei16, I32, u32_0ImmPred, PS_storerhabs>;
2148 def: Storea_pat<store, I32, u32_0ImmPred, PS_storeriabs>;
Krzysztof Parzyszek7aca2fd2017-06-09 15:26:21 +00002149 def: Storea_pat<store, I64, u32_0ImmPred, PS_storerdabs>;
2150
2151 def: Stoream_pat<truncstorei8, I64, u32_0ImmPred, LoReg, PS_storerbabs>;
2152 def: Stoream_pat<truncstorei16, I64, u32_0ImmPred, LoReg, PS_storerhabs>;
2153 def: Stoream_pat<truncstorei32, I64, u32_0ImmPred, LoReg, PS_storeriabs>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002154}
2155
2156let AddedComplexity = 30 in {
2157 def: Loada_pat<load, i32, u32_0ImmPred, PS_loadriabs>;
2158 def: Loada_pat<sextloadi8, i32, u32_0ImmPred, PS_loadrbabs>;
2159 def: Loada_pat<zextloadi8, i32, u32_0ImmPred, PS_loadrubabs>;
2160 def: Loada_pat<sextloadi16, i32, u32_0ImmPred, PS_loadrhabs>;
2161 def: Loada_pat<zextloadi16, i32, u32_0ImmPred, PS_loadruhabs>;
Krzysztof Parzyszek7aca2fd2017-06-09 15:26:21 +00002162 def: Loada_pat<load, i64, u32_0ImmPred, PS_loadrdabs>;
2163
2164 def: Loadam_pat<extloadi8, i64, u32_0ImmPred, ToZext64, PS_loadrubabs>;
2165 def: Loadam_pat<sextloadi8, i64, u32_0ImmPred, ToSext64, PS_loadrbabs>;
2166 def: Loadam_pat<zextloadi8, i64, u32_0ImmPred, ToZext64, PS_loadrubabs>;
2167
2168 def: Loadam_pat<extloadi16, i64, u32_0ImmPred, ToZext64, PS_loadruhabs>;
2169 def: Loadam_pat<sextloadi16, i64, u32_0ImmPred, ToSext64, PS_loadrhabs>;
2170 def: Loadam_pat<zextloadi16, i64, u32_0ImmPred, ToZext64, PS_loadruhabs>;
2171
2172 def: Loadam_pat<extloadi32, i64, u32_0ImmPred, ToZext64, PS_loadriabs>;
2173 def: Loadam_pat<sextloadi32, i64, u32_0ImmPred, ToSext64, PS_loadriabs>;
2174 def: Loadam_pat<zextloadi32, i64, u32_0ImmPred, ToZext64, PS_loadriabs>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002175}
2176
2177// Indexed store word - global address.
2178// memw(Rs+#u6:2)=#S8
2179let AddedComplexity = 100 in
2180defm: Storex_add_pat<store, addrga, u6_2ImmPred, S4_storeiri_io>;
2181
2182// Load from a global address that has only one use in the current basic block.
2183let AddedComplexity = 100 in {
2184 def: Loada_pat<extloadi8, i32, addrga, PS_loadrubabs>;
2185 def: Loada_pat<sextloadi8, i32, addrga, PS_loadrbabs>;
2186 def: Loada_pat<zextloadi8, i32, addrga, PS_loadrubabs>;
2187
2188 def: Loada_pat<extloadi16, i32, addrga, PS_loadruhabs>;
2189 def: Loada_pat<sextloadi16, i32, addrga, PS_loadrhabs>;
2190 def: Loada_pat<zextloadi16, i32, addrga, PS_loadruhabs>;
2191
2192 def: Loada_pat<load, i32, addrga, PS_loadriabs>;
2193 def: Loada_pat<load, i64, addrga, PS_loadrdabs>;
2194}
2195
2196// Store to a global address that has only one use in the current basic block.
2197let AddedComplexity = 100 in {
2198 def: Storea_pat<truncstorei8, I32, addrga, PS_storerbabs>;
2199 def: Storea_pat<truncstorei16, I32, addrga, PS_storerhabs>;
2200 def: Storea_pat<store, I32, addrga, PS_storeriabs>;
2201 def: Storea_pat<store, I64, addrga, PS_storerdabs>;
2202
2203 def: Stoream_pat<truncstorei32, I64, addrga, LoReg, PS_storeriabs>;
2204}
2205
2206// i8/i16/i32 -> i64 loads
2207// We need a complexity of 120 here to override preceding handling of
2208// zextload.
2209let AddedComplexity = 120 in {
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00002210 def: Loadam_pat<extloadi8, i64, addrga, ToZext64, PS_loadrubabs>;
2211 def: Loadam_pat<sextloadi8, i64, addrga, ToSext64, PS_loadrbabs>;
2212 def: Loadam_pat<zextloadi8, i64, addrga, ToZext64, PS_loadrubabs>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002213
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00002214 def: Loadam_pat<extloadi16, i64, addrga, ToZext64, PS_loadruhabs>;
2215 def: Loadam_pat<sextloadi16, i64, addrga, ToSext64, PS_loadrhabs>;
2216 def: Loadam_pat<zextloadi16, i64, addrga, ToZext64, PS_loadruhabs>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002217
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00002218 def: Loadam_pat<extloadi32, i64, addrga, ToZext64, PS_loadriabs>;
2219 def: Loadam_pat<sextloadi32, i64, addrga, ToSext64, PS_loadriabs>;
2220 def: Loadam_pat<zextloadi32, i64, addrga, ToZext64, PS_loadriabs>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002221}
2222
2223let AddedComplexity = 100 in {
2224 def: Loada_pat<extloadi8, i32, addrgp, PS_loadrubabs>;
2225 def: Loada_pat<sextloadi8, i32, addrgp, PS_loadrbabs>;
2226 def: Loada_pat<zextloadi8, i32, addrgp, PS_loadrubabs>;
2227
2228 def: Loada_pat<extloadi16, i32, addrgp, PS_loadruhabs>;
2229 def: Loada_pat<sextloadi16, i32, addrgp, PS_loadrhabs>;
2230 def: Loada_pat<zextloadi16, i32, addrgp, PS_loadruhabs>;
2231
2232 def: Loada_pat<load, i32, addrgp, PS_loadriabs>;
2233 def: Loada_pat<load, i64, addrgp, PS_loadrdabs>;
2234}
2235
2236let AddedComplexity = 100 in {
2237 def: Storea_pat<truncstorei8, I32, addrgp, PS_storerbabs>;
2238 def: Storea_pat<truncstorei16, I32, addrgp, PS_storerhabs>;
2239 def: Storea_pat<store, I32, addrgp, PS_storeriabs>;
2240 def: Storea_pat<store, I64, addrgp, PS_storerdabs>;
2241}
2242
2243def: Loada_pat<atomic_load_8, i32, addrgp, PS_loadrubabs>;
2244def: Loada_pat<atomic_load_16, i32, addrgp, PS_loadruhabs>;
2245def: Loada_pat<atomic_load_32, i32, addrgp, PS_loadriabs>;
2246def: Loada_pat<atomic_load_64, i64, addrgp, PS_loadrdabs>;
2247
2248def: Storea_pat<SwapSt<atomic_store_8>, I32, addrgp, PS_storerbabs>;
2249def: Storea_pat<SwapSt<atomic_store_16>, I32, addrgp, PS_storerhabs>;
2250def: Storea_pat<SwapSt<atomic_store_32>, I32, addrgp, PS_storeriabs>;
2251def: Storea_pat<SwapSt<atomic_store_64>, I64, addrgp, PS_storerdabs>;
2252
Krzysztof Parzyszek5eef92e2017-07-17 15:45:45 +00002253// Prefer this pattern to S2_asl_i_p_or for the special case of joining
2254// two 32-bit words into a 64-bit word.
2255let AddedComplexity = 200 in
2256def: Pat<(or (shl (Aext64 I32:$a), (i32 32)), (Zext64 I32:$b)),
2257 (A2_combinew I32:$a, I32:$b)>;
2258
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +00002259def: Pat<(or (or (or (shl (i64 (zext (and I32:$b, (i32 65535)))), (i32 16)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00002260 (i64 (zext (i32 (and I32:$a, (i32 65535)))))),
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +00002261 (shl (i64 (anyext (and I32:$c, (i32 65535)))), (i32 32))),
Krzysztof Parzyszek84755102016-11-06 17:56:48 +00002262 (shl (Aext64 I32:$d), (i32 48))),
Krzysztof Parzyszek601d7eb2016-11-09 14:16:29 +00002263 (A2_combinew (A2_combine_ll I32:$d, I32:$c),
2264 (A2_combine_ll I32:$b, I32:$a))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002265
2266// We need custom lowering of ISD::PREFETCH into HexagonISD::DCFETCH
2267// because the SDNode ISD::PREFETCH has properties MayLoad and MayStore.
2268// We don't really want either one here.
2269def SDTHexagonDCFETCH : SDTypeProfile<0, 2, [SDTCisPtrTy<0>,SDTCisInt<1>]>;
2270def HexagonDCFETCH : SDNode<"HexagonISD::DCFETCH", SDTHexagonDCFETCH,
2271 [SDNPHasChain]>;
2272
2273def: Pat<(HexagonDCFETCH IntRegs:$Rs, u11_3ImmPred:$u11_3),
2274 (Y2_dcfetchbo IntRegs:$Rs, imm:$u11_3)>;
2275def: Pat<(HexagonDCFETCH (i32 (add IntRegs:$Rs, u11_3ImmPred:$u11_3)), (i32 0)),
2276 (Y2_dcfetchbo IntRegs:$Rs, imm:$u11_3)>;
2277
2278def f32ImmPred : PatLeaf<(f32 fpimm:$F)>;
2279def f64ImmPred : PatLeaf<(f64 fpimm:$F)>;
2280
2281def ftoi : SDNodeXForm<fpimm, [{
2282 APInt I = N->getValueAPF().bitcastToAPInt();
2283 return CurDAG->getTargetConstant(I.getZExtValue(), SDLoc(N),
2284 MVT::getIntegerVT(I.getBitWidth()));
2285}]>;
2286
2287
Krzysztof Parzyszekc93815e2016-11-06 18:13:14 +00002288def: Pat<(sra (i64 (add (sra I64:$src1, u6_0ImmPred:$src2), 1)), (i32 1)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002289 (S2_asr_i_p_rnd I64:$src1, imm:$src2)>;
2290
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002291let AddedComplexity = 20 in {
2292 defm: Loadx_pat<load, f32, s30_2ImmPred, L2_loadri_io>;
2293 defm: Loadx_pat<load, f64, s29_3ImmPred, L2_loadrd_io>;
2294}
2295
2296let AddedComplexity = 60 in {
2297 defm : T_LoadAbsReg_Pat <load, L4_loadri_ur, f32>;
2298 defm : T_LoadAbsReg_Pat <load, L4_loadrd_ur, f64>;
2299}
2300
2301let AddedComplexity = 40 in {
2302 def: Loadxs_pat<load, f32, L4_loadri_rr>;
2303 def: Loadxs_pat<load, f64, L4_loadrd_rr>;
2304}
2305
2306let AddedComplexity = 20 in {
2307 def: Loadxs_simple_pat<load, f32, L4_loadri_rr>;
2308 def: Loadxs_simple_pat<load, f64, L4_loadrd_rr>;
2309}
2310
2311let AddedComplexity = 80 in {
2312 def: Loada_pat<load, f32, u32_0ImmPred, PS_loadriabs>;
2313 def: Loada_pat<load, f32, addrga, PS_loadriabs>;
2314 def: Loada_pat<load, f64, addrga, PS_loadrdabs>;
2315}
2316
2317let AddedComplexity = 100 in {
2318 def: LoadGP_pats <load, L2_loadrigp, f32>;
2319 def: LoadGP_pats <load, L2_loadrdgp, f64>;
2320}
2321
2322let AddedComplexity = 20 in {
2323 defm: Storex_pat<store, F32, s30_2ImmPred, S2_storeri_io>;
2324 defm: Storex_pat<store, F64, s29_3ImmPred, S2_storerd_io>;
2325}
2326
2327// Simple patterns should be tried with the least priority.
2328def: Storex_simple_pat<store, F32, S2_storeri_io>;
2329def: Storex_simple_pat<store, F64, S2_storerd_io>;
2330
2331let AddedComplexity = 60 in {
2332 defm : T_StoreAbsReg_Pats <S4_storeri_ur, IntRegs, f32, store>;
2333 defm : T_StoreAbsReg_Pats <S4_storerd_ur, DoubleRegs, f64, store>;
2334}
2335
2336let AddedComplexity = 40 in {
2337 def: Storexs_pat<store, F32, S4_storeri_rr>;
2338 def: Storexs_pat<store, F64, S4_storerd_rr>;
2339}
2340
2341let AddedComplexity = 20 in {
2342 def: Store_rr_pat<store, F32, S4_storeri_rr>;
2343 def: Store_rr_pat<store, F64, S4_storerd_rr>;
2344}
2345
2346let AddedComplexity = 80 in {
2347 def: Storea_pat<store, F32, addrga, PS_storeriabs>;
2348 def: Storea_pat<store, F64, addrga, PS_storerdabs>;
2349}
2350
2351let AddedComplexity = 100 in {
2352 def: Storea_pat<store, F32, addrgp, S2_storerigp>;
2353 def: Storea_pat<store, F64, addrgp, S2_storerdgp>;
2354}
2355
2356defm: Storex_pat<store, F32, s30_2ImmPred, S2_storeri_io>;
2357defm: Storex_pat<store, F64, s29_3ImmPred, S2_storerd_io>;
2358def: Storex_simple_pat<store, F32, S2_storeri_io>;
2359def: Storex_simple_pat<store, F64, S2_storerd_io>;
2360
2361def: Pat<(fadd F32:$src1, F32:$src2),
2362 (F2_sfadd F32:$src1, F32:$src2)>;
2363
2364def: Pat<(fsub F32:$src1, F32:$src2),
2365 (F2_sfsub F32:$src1, F32:$src2)>;
2366
2367def: Pat<(fmul F32:$src1, F32:$src2),
2368 (F2_sfmpy F32:$src1, F32:$src2)>;
2369
2370let Predicates = [HasV5T] in {
2371 def: Pat<(f32 (fminnum F32:$Rs, F32:$Rt)), (F2_sfmin F32:$Rs, F32:$Rt)>;
2372 def: Pat<(f32 (fmaxnum F32:$Rs, F32:$Rt)), (F2_sfmax F32:$Rs, F32:$Rt)>;
2373}
2374
2375let AddedComplexity = 100, Predicates = [HasV5T] in {
2376 class SfSel12<PatFrag Cmp, InstHexagon MI>
2377 : Pat<(select (i1 (Cmp F32:$Rs, F32:$Rt)), F32:$Rs, F32:$Rt),
2378 (MI F32:$Rs, F32:$Rt)>;
2379 class SfSel21<PatFrag Cmp, InstHexagon MI>
2380 : Pat<(select (i1 (Cmp F32:$Rs, F32:$Rt)), F32:$Rt, F32:$Rs),
2381 (MI F32:$Rs, F32:$Rt)>;
2382
2383 def: SfSel12<setolt, F2_sfmin>;
2384 def: SfSel12<setole, F2_sfmin>;
2385 def: SfSel12<setogt, F2_sfmax>;
2386 def: SfSel12<setoge, F2_sfmax>;
2387 def: SfSel21<setolt, F2_sfmax>;
2388 def: SfSel21<setole, F2_sfmax>;
2389 def: SfSel21<setogt, F2_sfmin>;
2390 def: SfSel21<setoge, F2_sfmin>;
2391}
2392
2393class T_fcmp32_pat<PatFrag OpNode, InstHexagon MI>
2394 : Pat<(i1 (OpNode F32:$src1, F32:$src2)),
2395 (MI F32:$src1, F32:$src2)>;
2396class T_fcmp64_pat<PatFrag OpNode, InstHexagon MI>
2397 : Pat<(i1 (OpNode F64:$src1, F64:$src2)),
2398 (MI F64:$src1, F64:$src2)>;
2399
2400def: T_fcmp32_pat<setoge, F2_sfcmpge>;
2401def: T_fcmp32_pat<setuo, F2_sfcmpuo>;
2402def: T_fcmp32_pat<setoeq, F2_sfcmpeq>;
2403def: T_fcmp32_pat<setogt, F2_sfcmpgt>;
2404
2405def: T_fcmp64_pat<setoge, F2_dfcmpge>;
2406def: T_fcmp64_pat<setuo, F2_dfcmpuo>;
2407def: T_fcmp64_pat<setoeq, F2_dfcmpeq>;
2408def: T_fcmp64_pat<setogt, F2_dfcmpgt>;
2409
2410let Predicates = [HasV5T] in
2411multiclass T_fcmp_pats<PatFrag cmpOp, InstHexagon IntMI, InstHexagon DoubleMI> {
2412 // IntRegs
2413 def: Pat<(i1 (cmpOp F32:$src1, F32:$src2)),
2414 (IntMI F32:$src1, F32:$src2)>;
2415 // DoubleRegs
2416 def: Pat<(i1 (cmpOp F64:$src1, F64:$src2)),
2417 (DoubleMI F64:$src1, F64:$src2)>;
2418}
2419
2420defm : T_fcmp_pats <seteq, F2_sfcmpeq, F2_dfcmpeq>;
2421defm : T_fcmp_pats <setgt, F2_sfcmpgt, F2_dfcmpgt>;
2422defm : T_fcmp_pats <setge, F2_sfcmpge, F2_dfcmpge>;
2423
2424//===----------------------------------------------------------------------===//
2425// Multiclass to define 'Def Pats' for unordered gt, ge, eq operations.
2426//===----------------------------------------------------------------------===//
2427let Predicates = [HasV5T] in
2428multiclass unord_Pats <PatFrag cmpOp, InstHexagon IntMI, InstHexagon DoubleMI> {
2429 // IntRegs
2430 def: Pat<(i1 (cmpOp F32:$src1, F32:$src2)),
2431 (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
2432 (IntMI F32:$src1, F32:$src2))>;
2433
2434 // DoubleRegs
2435 def: Pat<(i1 (cmpOp F64:$src1, F64:$src2)),
2436 (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
2437 (DoubleMI F64:$src1, F64:$src2))>;
2438}
2439
2440defm : unord_Pats <setuge, F2_sfcmpge, F2_dfcmpge>;
2441defm : unord_Pats <setugt, F2_sfcmpgt, F2_dfcmpgt>;
2442defm : unord_Pats <setueq, F2_sfcmpeq, F2_dfcmpeq>;
2443
2444//===----------------------------------------------------------------------===//
2445// Multiclass to define 'Def Pats' for the following dags:
2446// seteq(setoeq(op1, op2), 0) -> not(setoeq(op1, op2))
2447// seteq(setoeq(op1, op2), 1) -> setoeq(op1, op2)
2448// setne(setoeq(op1, op2), 0) -> setoeq(op1, op2)
2449// setne(setoeq(op1, op2), 1) -> not(setoeq(op1, op2))
2450//===----------------------------------------------------------------------===//
2451let Predicates = [HasV5T] in
2452multiclass eq_ordgePats <PatFrag cmpOp, InstHexagon IntMI,
2453 InstHexagon DoubleMI> {
2454 // IntRegs
2455 def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
2456 (C2_not (IntMI F32:$src1, F32:$src2))>;
2457 def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
2458 (IntMI F32:$src1, F32:$src2)>;
2459 def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
2460 (IntMI F32:$src1, F32:$src2)>;
2461 def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
2462 (C2_not (IntMI F32:$src1, F32:$src2))>;
2463
2464 // DoubleRegs
2465 def : Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
2466 (C2_not (DoubleMI F64:$src1, F64:$src2))>;
2467 def : Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 1)),
2468 (DoubleMI F64:$src1, F64:$src2)>;
2469 def : Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
2470 (DoubleMI F64:$src1, F64:$src2)>;
2471 def : Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 1)),
2472 (C2_not (DoubleMI F64:$src1, F64:$src2))>;
2473}
2474
2475defm : eq_ordgePats<setoeq, F2_sfcmpeq, F2_dfcmpeq>;
2476defm : eq_ordgePats<setoge, F2_sfcmpge, F2_dfcmpge>;
2477defm : eq_ordgePats<setogt, F2_sfcmpgt, F2_dfcmpgt>;
2478
2479//===----------------------------------------------------------------------===//
2480// Multiclass to define 'Def Pats' for the following dags:
2481// seteq(setolt(op1, op2), 0) -> not(setogt(op2, op1))
2482// seteq(setolt(op1, op2), 1) -> setogt(op2, op1)
2483// setne(setolt(op1, op2), 0) -> setogt(op2, op1)
2484// setne(setolt(op1, op2), 1) -> not(setogt(op2, op1))
2485//===----------------------------------------------------------------------===//
2486let Predicates = [HasV5T] in
2487multiclass eq_ordltPats <PatFrag cmpOp, InstHexagon IntMI,
2488 InstHexagon DoubleMI> {
2489 // IntRegs
2490 def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
2491 (C2_not (IntMI F32:$src2, F32:$src1))>;
2492 def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
2493 (IntMI F32:$src2, F32:$src1)>;
2494 def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
2495 (IntMI F32:$src2, F32:$src1)>;
2496 def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
2497 (C2_not (IntMI F32:$src2, F32:$src1))>;
2498
2499 // DoubleRegs
2500 def: Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
2501 (C2_not (DoubleMI F64:$src2, F64:$src1))>;
2502 def: Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 1)),
2503 (DoubleMI F64:$src2, F64:$src1)>;
2504 def: Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
2505 (DoubleMI F64:$src2, F64:$src1)>;
2506 def: Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
2507 (C2_not (DoubleMI F64:$src2, F64:$src1))>;
2508}
2509
2510defm : eq_ordltPats<setole, F2_sfcmpge, F2_dfcmpge>;
2511defm : eq_ordltPats<setolt, F2_sfcmpgt, F2_dfcmpgt>;
2512
2513
2514// o. seto inverse of setuo. http://llvm.org/docs/LangRef.html#i_fcmp
2515let Predicates = [HasV5T] in {
2516 def: Pat<(i1 (seto F32:$src1, F32:$src2)),
2517 (C2_not (F2_sfcmpuo F32:$src2, F32:$src1))>;
2518 def: Pat<(i1 (seto F32:$src1, f32ImmPred:$src2)),
2519 (C2_not (F2_sfcmpuo (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>;
2520 def: Pat<(i1 (seto F64:$src1, F64:$src2)),
2521 (C2_not (F2_dfcmpuo F64:$src2, F64:$src1))>;
2522 def: Pat<(i1 (seto F64:$src1, f64ImmPred:$src2)),
2523 (C2_not (F2_dfcmpuo (CONST64 (ftoi $src2)), F64:$src1))>;
2524}
2525
2526// Ordered lt.
2527let Predicates = [HasV5T] in {
2528 def: Pat<(i1 (setolt F32:$src1, F32:$src2)),
2529 (F2_sfcmpgt F32:$src2, F32:$src1)>;
2530 def: Pat<(i1 (setolt F32:$src1, f32ImmPred:$src2)),
2531 (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>;
2532 def: Pat<(i1 (setolt F64:$src1, F64:$src2)),
2533 (F2_dfcmpgt F64:$src2, F64:$src1)>;
2534 def: Pat<(i1 (setolt F64:$src1, f64ImmPred:$src2)),
2535 (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1)>;
2536}
2537
2538// Unordered lt.
2539let Predicates = [HasV5T] in {
2540 def: Pat<(i1 (setult F32:$src1, F32:$src2)),
2541 (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
2542 (F2_sfcmpgt F32:$src2, F32:$src1))>;
2543 def: Pat<(i1 (setult F32:$src1, f32ImmPred:$src2)),
2544 (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))),
2545 (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>;
2546 def: Pat<(i1 (setult F64:$src1, F64:$src2)),
2547 (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
2548 (F2_dfcmpgt F64:$src2, F64:$src1))>;
2549 def: Pat<(i1 (setult F64:$src1, f64ImmPred:$src2)),
2550 (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))),
2551 (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1))>;
2552}
2553
2554// Ordered le.
2555let Predicates = [HasV5T] in {
2556 // rs <= rt -> rt >= rs.
2557 def: Pat<(i1 (setole F32:$src1, F32:$src2)),
2558 (F2_sfcmpge F32:$src2, F32:$src1)>;
2559 def: Pat<(i1 (setole F32:$src1, f32ImmPred:$src2)),
2560 (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>;
2561
2562 // Rss <= Rtt -> Rtt >= Rss.
2563 def: Pat<(i1 (setole F64:$src1, F64:$src2)),
2564 (F2_dfcmpge F64:$src2, F64:$src1)>;
2565 def: Pat<(i1 (setole F64:$src1, f64ImmPred:$src2)),
2566 (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1)>;
2567}
2568
2569// Unordered le.
2570let Predicates = [HasV5T] in {
2571// rs <= rt -> rt >= rs.
2572 def: Pat<(i1 (setule F32:$src1, F32:$src2)),
2573 (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
2574 (F2_sfcmpge F32:$src2, F32:$src1))>;
2575 def: Pat<(i1 (setule F32:$src1, f32ImmPred:$src2)),
2576 (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))),
2577 (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>;
2578 def: Pat<(i1 (setule F64:$src1, F64:$src2)),
2579 (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
2580 (F2_dfcmpge F64:$src2, F64:$src1))>;
2581 def: Pat<(i1 (setule F64:$src1, f64ImmPred:$src2)),
2582 (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))),
2583 (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1))>;
2584}
2585
2586// Ordered ne.
2587let Predicates = [HasV5T] in {
2588 def: Pat<(i1 (setone F32:$src1, F32:$src2)),
2589 (C2_not (F2_sfcmpeq F32:$src1, F32:$src2))>;
2590 def: Pat<(i1 (setone F64:$src1, F64:$src2)),
2591 (C2_not (F2_dfcmpeq F64:$src1, F64:$src2))>;
2592 def: Pat<(i1 (setone F32:$src1, f32ImmPred:$src2)),
2593 (C2_not (F2_sfcmpeq F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))))>;
2594 def: Pat<(i1 (setone F64:$src1, f64ImmPred:$src2)),
2595 (C2_not (F2_dfcmpeq F64:$src1, (CONST64 (ftoi $src2))))>;
2596}
2597
2598// Unordered ne.
2599let Predicates = [HasV5T] in {
2600 def: Pat<(i1 (setune F32:$src1, F32:$src2)),
2601 (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
2602 (C2_not (F2_sfcmpeq F32:$src1, F32:$src2)))>;
2603 def: Pat<(i1 (setune F64:$src1, F64:$src2)),
2604 (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
2605 (C2_not (F2_dfcmpeq F64:$src1, F64:$src2)))>;
2606 def: Pat<(i1 (setune F32:$src1, f32ImmPred:$src2)),
2607 (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))),
2608 (C2_not (F2_sfcmpeq F32:$src1,
2609 (f32 (A2_tfrsi (ftoi $src2))))))>;
2610 def: Pat<(i1 (setune F64:$src1, f64ImmPred:$src2)),
2611 (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))),
2612 (C2_not (F2_dfcmpeq F64:$src1,
2613 (CONST64 (ftoi $src2)))))>;
2614}
2615
2616// Besides set[o|u][comparions], we also need set[comparisons].
2617let Predicates = [HasV5T] in {
2618 // lt.
2619 def: Pat<(i1 (setlt F32:$src1, F32:$src2)),
2620 (F2_sfcmpgt F32:$src2, F32:$src1)>;
2621 def: Pat<(i1 (setlt F32:$src1, f32ImmPred:$src2)),
2622 (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>;
2623 def: Pat<(i1 (setlt F64:$src1, F64:$src2)),
2624 (F2_dfcmpgt F64:$src2, F64:$src1)>;
2625 def: Pat<(i1 (setlt F64:$src1, f64ImmPred:$src2)),
2626 (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1)>;
2627
2628 // le.
2629 // rs <= rt -> rt >= rs.
2630 def: Pat<(i1 (setle F32:$src1, F32:$src2)),
2631 (F2_sfcmpge F32:$src2, F32:$src1)>;
2632 def: Pat<(i1 (setle F32:$src1, f32ImmPred:$src2)),
2633 (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>;
2634
2635 // Rss <= Rtt -> Rtt >= Rss.
2636 def: Pat<(i1 (setle F64:$src1, F64:$src2)),
2637 (F2_dfcmpge F64:$src2, F64:$src1)>;
2638 def: Pat<(i1 (setle F64:$src1, f64ImmPred:$src2)),
2639 (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1)>;
2640
2641 // ne.
2642 def: Pat<(i1 (setne F32:$src1, F32:$src2)),
2643 (C2_not (F2_sfcmpeq F32:$src1, F32:$src2))>;
2644 def: Pat<(i1 (setne F64:$src1, F64:$src2)),
2645 (C2_not (F2_dfcmpeq F64:$src1, F64:$src2))>;
2646 def: Pat<(i1 (setne F32:$src1, f32ImmPred:$src2)),
2647 (C2_not (F2_sfcmpeq F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))))>;
2648 def: Pat<(i1 (setne F64:$src1, f64ImmPred:$src2)),
2649 (C2_not (F2_dfcmpeq F64:$src1, (CONST64 (ftoi $src2))))>;
2650}
2651
2652
2653def: Pat<(f64 (fpextend F32:$Rs)), (F2_conv_sf2df F32:$Rs)>;
2654def: Pat<(f32 (fpround F64:$Rs)), (F2_conv_df2sf F64:$Rs)>;
2655
2656def: Pat<(f32 (sint_to_fp I32:$Rs)), (F2_conv_w2sf I32:$Rs)>;
2657def: Pat<(f32 (sint_to_fp I64:$Rs)), (F2_conv_d2sf I64:$Rs)>;
2658def: Pat<(f64 (sint_to_fp I32:$Rs)), (F2_conv_w2df I32:$Rs)>;
2659def: Pat<(f64 (sint_to_fp I64:$Rs)), (F2_conv_d2df I64:$Rs)>;
2660
2661def: Pat<(f32 (uint_to_fp I32:$Rs)), (F2_conv_uw2sf I32:$Rs)>;
2662def: Pat<(f32 (uint_to_fp I64:$Rs)), (F2_conv_ud2sf I64:$Rs)>;
2663def: Pat<(f64 (uint_to_fp I32:$Rs)), (F2_conv_uw2df I32:$Rs)>;
2664def: Pat<(f64 (uint_to_fp I64:$Rs)), (F2_conv_ud2df I64:$Rs)>;
2665
2666def: Pat<(i32 (fp_to_sint F32:$Rs)), (F2_conv_sf2w_chop F32:$Rs)>;
2667def: Pat<(i32 (fp_to_sint F64:$Rs)), (F2_conv_df2w_chop F64:$Rs)>;
2668def: Pat<(i64 (fp_to_sint F32:$Rs)), (F2_conv_sf2d_chop F32:$Rs)>;
2669def: Pat<(i64 (fp_to_sint F64:$Rs)), (F2_conv_df2d_chop F64:$Rs)>;
2670
2671def: Pat<(i32 (fp_to_uint F32:$Rs)), (F2_conv_sf2uw_chop F32:$Rs)>;
2672def: Pat<(i32 (fp_to_uint F64:$Rs)), (F2_conv_df2uw_chop F64:$Rs)>;
2673def: Pat<(i64 (fp_to_uint F32:$Rs)), (F2_conv_sf2ud_chop F32:$Rs)>;
2674def: Pat<(i64 (fp_to_uint F64:$Rs)), (F2_conv_df2ud_chop F64:$Rs)>;
2675
2676// Bitcast is different than [fp|sint|uint]_to_[sint|uint|fp].
2677let Predicates = [HasV5T] in {
2678 def: Pat <(i32 (bitconvert F32:$src)), (I32:$src)>;
2679 def: Pat <(f32 (bitconvert I32:$src)), (F32:$src)>;
2680 def: Pat <(i64 (bitconvert F64:$src)), (I64:$src)>;
2681 def: Pat <(f64 (bitconvert I64:$src)), (F64:$src)>;
2682}
2683
2684def : Pat <(fma F32:$src2, F32:$src3, F32:$src1),
2685 (F2_sffma F32:$src1, F32:$src2, F32:$src3)>;
2686
2687def : Pat <(fma (fneg F32:$src2), F32:$src3, F32:$src1),
2688 (F2_sffms F32:$src1, F32:$src2, F32:$src3)>;
2689
2690def : Pat <(fma F32:$src2, (fneg F32:$src3), F32:$src1),
2691 (F2_sffms F32:$src1, F32:$src2, F32:$src3)>;
2692
2693def: Pat<(select I1:$Pu, F32:$Rs, f32ImmPred:$imm),
2694 (C2_muxir I1:$Pu, F32:$Rs, (ftoi $imm))>,
2695 Requires<[HasV5T]>;
2696
2697def: Pat<(select I1:$Pu, f32ImmPred:$imm, F32:$Rt),
2698 (C2_muxri I1:$Pu, (ftoi $imm), F32:$Rt)>,
2699 Requires<[HasV5T]>;
2700
2701def: Pat<(select I1:$src1, F32:$src2, F32:$src3),
2702 (C2_mux I1:$src1, F32:$src2, F32:$src3)>,
2703 Requires<[HasV5T]>;
2704
2705def: Pat<(select (i1 (setult F32:$src1, F32:$src2)), F32:$src3, F32:$src4),
2706 (C2_mux (F2_sfcmpgt F32:$src2, F32:$src1), F32:$src4, F32:$src3)>,
2707 Requires<[HasV5T]>;
2708
2709def: Pat<(select I1:$src1, F64:$src2, F64:$src3),
2710 (C2_vmux I1:$src1, F64:$src2, F64:$src3)>,
2711 Requires<[HasV5T]>;
2712
2713def: Pat<(select (i1 (setult F64:$src1, F64:$src2)), F64:$src3, F64:$src4),
2714 (C2_vmux (F2_dfcmpgt F64:$src2, F64:$src1), F64:$src3, F64:$src4)>,
2715 Requires<[HasV5T]>;
2716
2717// Map from p0 = pnot(p0); r0 = select(p0, #i, r1)
2718// => r0 = mux(p0, #i, r1)
2719def: Pat<(select (not I1:$src1), f32ImmPred:$src2, F32:$src3),
2720 (C2_muxir I1:$src1, F32:$src3, (ftoi $src2))>,
2721 Requires<[HasV5T]>;
2722
2723// Map from p0 = pnot(p0); r0 = mux(p0, r1, #i)
2724// => r0 = mux(p0, r1, #i)
2725def: Pat<(select (not I1:$src1), F32:$src2, f32ImmPred:$src3),
2726 (C2_muxri I1:$src1, (ftoi $src3), F32:$src2)>,
2727 Requires<[HasV5T]>;
2728
2729def: Pat<(i32 (fp_to_sint F64:$src1)),
2730 (LoReg (F2_conv_df2d_chop F64:$src1))>,
2731 Requires<[HasV5T]>;
2732
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00002733def : Pat <(fabs F32:$src1),
2734 (S2_clrbit_i F32:$src1, 31)>,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002735 Requires<[HasV5T]>;
2736
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00002737def : Pat <(fneg F32:$src1),
2738 (S2_togglebit_i F32:$src1, 31)>,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002739 Requires<[HasV5T]>;
2740
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +00002741def: Pat<(fabs F64:$Rs),
2742 (REG_SEQUENCE DoubleRegs,
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00002743 (S2_clrbit_i (HiReg $Rs), 31), isub_hi,
2744 (i32 (LoReg $Rs)), isub_lo)>;
Krzysztof Parzyszek39d14f32016-11-06 20:55:57 +00002745
2746def: Pat<(fneg F64:$Rs),
2747 (REG_SEQUENCE DoubleRegs,
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00002748 (S2_togglebit_i (HiReg $Rs), 31), isub_hi,
2749 (i32 (LoReg $Rs)), isub_lo)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002750
Krzysztof Parzyszek7aca2fd2017-06-09 15:26:21 +00002751def: Pat<(mul I64:$Rss, I64:$Rtt),
2752 (A2_combinew
2753 (M2_maci (M2_maci (HiReg (M2_dpmpyuu_s0 (LoReg $Rss), (LoReg $Rtt))),
2754 (LoReg $Rss),
2755 (HiReg $Rtt)),
2756 (LoReg $Rtt),
2757 (HiReg $Rss)),
2758 (LoReg (M2_dpmpyuu_s0 (LoReg $Rss), (LoReg $Rtt))))>;
2759
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002760def alignedload : PatFrag<(ops node:$addr), (load $addr), [{
2761 return isAlignedMemNode(dyn_cast<MemSDNode>(N));
2762}]>;
2763
2764def unalignedload : PatFrag<(ops node:$addr), (load $addr), [{
2765 return !isAlignedMemNode(dyn_cast<MemSDNode>(N));
2766}]>;
2767
2768def alignedstore : PatFrag<(ops node:$val, node:$addr), (store $val, $addr), [{
2769 return isAlignedMemNode(dyn_cast<MemSDNode>(N));
2770}]>;
2771
2772def unalignedstore : PatFrag<(ops node:$val, node:$addr), (store $val, $addr), [{
2773 return !isAlignedMemNode(dyn_cast<MemSDNode>(N));
2774}]>;
2775
2776
2777multiclass vS32b_ai_pats <ValueType VTSgl, ValueType VTDbl> {
2778 // Aligned stores
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002779 def : Pat<(alignednontemporalstore (VTSgl VectorRegs:$src1), IntRegs:$addr),
2780 (V6_vS32b_nt_ai IntRegs:$addr, 0, (VTSgl VectorRegs:$src1))>,
2781 Requires<[UseHVXSgl]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002782 def : Pat<(alignedstore (VTSgl VectorRegs:$src1), IntRegs:$addr),
2783 (V6_vS32b_ai IntRegs:$addr, 0, (VTSgl VectorRegs:$src1))>,
2784 Requires<[UseHVXSgl]>;
2785 def : Pat<(unalignedstore (VTSgl VectorRegs:$src1), IntRegs:$addr),
2786 (V6_vS32Ub_ai IntRegs:$addr, 0, (VTSgl VectorRegs:$src1))>,
2787 Requires<[UseHVXSgl]>;
2788
2789 // 128B Aligned stores
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002790 def : Pat<(alignednontemporalstore (VTDbl VectorRegs128B:$src1), IntRegs:$addr),
2791 (V6_vS32b_nt_ai_128B IntRegs:$addr, 0, (VTDbl VectorRegs128B:$src1))>,
2792 Requires<[UseHVXDbl]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002793 def : Pat<(alignedstore (VTDbl VectorRegs128B:$src1), IntRegs:$addr),
2794 (V6_vS32b_ai_128B IntRegs:$addr, 0, (VTDbl VectorRegs128B:$src1))>,
2795 Requires<[UseHVXDbl]>;
2796 def : Pat<(unalignedstore (VTDbl VectorRegs128B:$src1), IntRegs:$addr),
2797 (V6_vS32Ub_ai_128B IntRegs:$addr, 0, (VTDbl VectorRegs128B:$src1))>,
2798 Requires<[UseHVXDbl]>;
2799
2800 // Fold Add R+OFF into vector store.
2801 let AddedComplexity = 10 in {
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002802 def : Pat<(alignednontemporalstore (VTSgl VectorRegs:$src1),
2803 (add IntRegs:$src2, Iss4_6:$offset)),
2804 (V6_vS32b_nt_ai IntRegs:$src2, Iss4_6:$offset,
2805 (VTSgl VectorRegs:$src1))>,
2806 Requires<[UseHVXSgl]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002807 def : Pat<(alignedstore (VTSgl VectorRegs:$src1),
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +00002808 (add IntRegs:$src2, Iss4_6:$offset)),
2809 (V6_vS32b_ai IntRegs:$src2, Iss4_6:$offset,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002810 (VTSgl VectorRegs:$src1))>,
2811 Requires<[UseHVXSgl]>;
2812 def : Pat<(unalignedstore (VTSgl VectorRegs:$src1),
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +00002813 (add IntRegs:$src2, Iss4_6:$offset)),
2814 (V6_vS32Ub_ai IntRegs:$src2, Iss4_6:$offset,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002815 (VTSgl VectorRegs:$src1))>,
2816 Requires<[UseHVXSgl]>;
2817
2818 // Fold Add R+OFF into vector store 128B.
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002819 def : Pat<(alignednontemporalstore (VTDbl VectorRegs128B:$src1),
2820 (add IntRegs:$src2, Iss4_7:$offset)),
2821 (V6_vS32b_nt_ai_128B IntRegs:$src2, Iss4_7:$offset,
2822 (VTDbl VectorRegs128B:$src1))>,
2823 Requires<[UseHVXDbl]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002824 def : Pat<(alignedstore (VTDbl VectorRegs128B:$src1),
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +00002825 (add IntRegs:$src2, Iss4_7:$offset)),
2826 (V6_vS32b_ai_128B IntRegs:$src2, Iss4_7:$offset,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002827 (VTDbl VectorRegs128B:$src1))>,
2828 Requires<[UseHVXDbl]>;
2829 def : Pat<(unalignedstore (VTDbl VectorRegs128B:$src1),
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +00002830 (add IntRegs:$src2, Iss4_7:$offset)),
2831 (V6_vS32Ub_ai_128B IntRegs:$src2, Iss4_7:$offset,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002832 (VTDbl VectorRegs128B:$src1))>,
2833 Requires<[UseHVXDbl]>;
2834 }
2835}
2836
2837defm : vS32b_ai_pats <v64i8, v128i8>;
2838defm : vS32b_ai_pats <v32i16, v64i16>;
2839defm : vS32b_ai_pats <v16i32, v32i32>;
2840defm : vS32b_ai_pats <v8i64, v16i64>;
2841
2842
2843multiclass vL32b_ai_pats <ValueType VTSgl, ValueType VTDbl> {
2844 // Aligned loads
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002845 def : Pat < (VTSgl (alignednontemporalload IntRegs:$addr)),
2846 (V6_vL32b_nt_ai IntRegs:$addr, 0) >,
2847 Requires<[UseHVXSgl]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002848 def : Pat < (VTSgl (alignedload IntRegs:$addr)),
2849 (V6_vL32b_ai IntRegs:$addr, 0) >,
2850 Requires<[UseHVXSgl]>;
2851 def : Pat < (VTSgl (unalignedload IntRegs:$addr)),
2852 (V6_vL32Ub_ai IntRegs:$addr, 0) >,
2853 Requires<[UseHVXSgl]>;
2854
2855 // 128B Load
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002856 def : Pat < (VTDbl (alignednontemporalload IntRegs:$addr)),
2857 (V6_vL32b_nt_ai_128B IntRegs:$addr, 0) >,
2858 Requires<[UseHVXDbl]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002859 def : Pat < (VTDbl (alignedload IntRegs:$addr)),
2860 (V6_vL32b_ai_128B IntRegs:$addr, 0) >,
2861 Requires<[UseHVXDbl]>;
2862 def : Pat < (VTDbl (unalignedload IntRegs:$addr)),
2863 (V6_vL32Ub_ai_128B IntRegs:$addr, 0) >,
2864 Requires<[UseHVXDbl]>;
2865
2866 // Fold Add R+OFF into vector load.
2867 let AddedComplexity = 10 in {
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002868 def : Pat<(VTDbl (alignednontemporalload (add IntRegs:$src2, Iss4_7:$offset))),
2869 (V6_vL32b_nt_ai_128B IntRegs:$src2, Iss4_7:$offset)>,
2870 Requires<[UseHVXDbl]>;
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +00002871 def : Pat<(VTDbl (alignedload (add IntRegs:$src2, Iss4_7:$offset))),
2872 (V6_vL32b_ai_128B IntRegs:$src2, Iss4_7:$offset)>,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002873 Requires<[UseHVXDbl]>;
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +00002874 def : Pat<(VTDbl (unalignedload (add IntRegs:$src2, Iss4_7:$offset))),
2875 (V6_vL32Ub_ai_128B IntRegs:$src2, Iss4_7:$offset)>,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002876 Requires<[UseHVXDbl]>;
2877
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002878 def : Pat<(VTSgl (alignednontemporalload (add IntRegs:$src2, Iss4_6:$offset))),
2879 (V6_vL32b_nt_ai IntRegs:$src2, Iss4_6:$offset)>,
2880 Requires<[UseHVXSgl]>;
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +00002881 def : Pat<(VTSgl (alignedload (add IntRegs:$src2, Iss4_6:$offset))),
2882 (V6_vL32b_ai IntRegs:$src2, Iss4_6:$offset)>,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002883 Requires<[UseHVXSgl]>;
Krzysztof Parzyszek058abf1a2017-04-06 17:28:21 +00002884 def : Pat<(VTSgl (unalignedload (add IntRegs:$src2, Iss4_6:$offset))),
2885 (V6_vL32Ub_ai IntRegs:$src2, Iss4_6:$offset)>,
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002886 Requires<[UseHVXSgl]>;
2887 }
2888}
2889
2890defm : vL32b_ai_pats <v64i8, v128i8>;
2891defm : vL32b_ai_pats <v32i16, v64i16>;
2892defm : vL32b_ai_pats <v16i32, v32i32>;
2893defm : vL32b_ai_pats <v8i64, v16i64>;
2894
2895multiclass STrivv_pats <ValueType VTSgl, ValueType VTDbl> {
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002896 def : Pat<(alignednontemporalstore (VTSgl VecDblRegs:$src1), IntRegs:$addr),
2897 (PS_vstorerw_nt_ai IntRegs:$addr, 0, (VTSgl VecDblRegs:$src1))>,
2898 Requires<[UseHVXSgl]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002899 def : Pat<(alignedstore (VTSgl VecDblRegs:$src1), IntRegs:$addr),
2900 (PS_vstorerw_ai IntRegs:$addr, 0, (VTSgl VecDblRegs:$src1))>,
2901 Requires<[UseHVXSgl]>;
2902 def : Pat<(unalignedstore (VTSgl VecDblRegs:$src1), IntRegs:$addr),
2903 (PS_vstorerwu_ai IntRegs:$addr, 0, (VTSgl VecDblRegs:$src1))>,
2904 Requires<[UseHVXSgl]>;
2905
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002906 def : Pat<(alignednontemporalstore (VTDbl VecDblRegs128B:$src1), IntRegs:$addr),
2907 (PS_vstorerw_nt_ai_128B IntRegs:$addr, 0,
2908 (VTDbl VecDblRegs128B:$src1))>,
2909 Requires<[UseHVXDbl]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002910 def : Pat<(alignedstore (VTDbl VecDblRegs128B:$src1), IntRegs:$addr),
2911 (PS_vstorerw_ai_128B IntRegs:$addr, 0,
2912 (VTDbl VecDblRegs128B:$src1))>,
2913 Requires<[UseHVXDbl]>;
2914 def : Pat<(unalignedstore (VTDbl VecDblRegs128B:$src1), IntRegs:$addr),
2915 (PS_vstorerwu_ai_128B IntRegs:$addr, 0,
2916 (VTDbl VecDblRegs128B:$src1))>,
2917 Requires<[UseHVXDbl]>;
2918}
2919
2920defm : STrivv_pats <v128i8, v256i8>;
2921defm : STrivv_pats <v64i16, v128i16>;
2922defm : STrivv_pats <v32i32, v64i32>;
2923defm : STrivv_pats <v16i64, v32i64>;
2924
2925multiclass LDrivv_pats <ValueType VTSgl, ValueType VTDbl> {
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002926 def : Pat<(VTSgl (alignednontemporalload I32:$addr)),
2927 (PS_vloadrw_nt_ai I32:$addr, 0)>,
2928 Requires<[UseHVXSgl]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002929 def : Pat<(VTSgl (alignedload I32:$addr)),
2930 (PS_vloadrw_ai I32:$addr, 0)>,
2931 Requires<[UseHVXSgl]>;
2932 def : Pat<(VTSgl (unalignedload I32:$addr)),
2933 (PS_vloadrwu_ai I32:$addr, 0)>,
2934 Requires<[UseHVXSgl]>;
2935
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002936 def : Pat<(VTDbl (alignednontemporalload I32:$addr)),
2937 (PS_vloadrw_nt_ai_128B I32:$addr, 0)>,
2938 Requires<[UseHVXDbl]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002939 def : Pat<(VTDbl (alignedload I32:$addr)),
2940 (PS_vloadrw_ai_128B I32:$addr, 0)>,
2941 Requires<[UseHVXDbl]>;
2942 def : Pat<(VTDbl (unalignedload I32:$addr)),
2943 (PS_vloadrwu_ai_128B I32:$addr, 0)>,
2944 Requires<[UseHVXDbl]>;
2945}
2946
2947defm : LDrivv_pats <v128i8, v256i8>;
2948defm : LDrivv_pats <v64i16, v128i16>;
2949defm : LDrivv_pats <v32i32, v64i32>;
2950defm : LDrivv_pats <v16i64, v32i64>;
2951
2952let Predicates = [HasV60T,UseHVXSgl] in {
2953 def: Pat<(select I1:$Pu, (v16i32 VectorRegs:$Vs), VectorRegs:$Vt),
2954 (PS_vselect I1:$Pu, VectorRegs:$Vs, VectorRegs:$Vt)>;
2955 def: Pat<(select I1:$Pu, (v32i32 VecDblRegs:$Vs), VecDblRegs:$Vt),
2956 (PS_wselect I1:$Pu, VecDblRegs:$Vs, VecDblRegs:$Vt)>;
2957}
2958let Predicates = [HasV60T,UseHVXDbl] in {
2959 def: Pat<(select I1:$Pu, (v32i32 VectorRegs128B:$Vs), VectorRegs128B:$Vt),
2960 (PS_vselect_128B I1:$Pu, VectorRegs128B:$Vs, VectorRegs128B:$Vt)>;
2961 def: Pat<(select I1:$Pu, (v64i32 VecDblRegs128B:$Vs), VecDblRegs128B:$Vt),
2962 (PS_wselect_128B I1:$Pu, VecDblRegs128B:$Vs, VecDblRegs128B:$Vt)>;
2963}
2964
2965
2966def SDTHexagonVCOMBINE: SDTypeProfile<1, 2, [SDTCisSameAs<1, 2>,
2967 SDTCisSubVecOfVec<1, 0>]>;
2968
2969def HexagonVCOMBINE: SDNode<"HexagonISD::VCOMBINE", SDTHexagonVCOMBINE>;
2970
2971def: Pat<(v32i32 (HexagonVCOMBINE (v16i32 VectorRegs:$Vs),
2972 (v16i32 VectorRegs:$Vt))),
2973 (V6_vcombine VectorRegs:$Vs, VectorRegs:$Vt)>,
2974 Requires<[UseHVXSgl]>;
2975def: Pat<(v64i32 (HexagonVCOMBINE (v32i32 VecDblRegs:$Vs),
2976 (v32i32 VecDblRegs:$Vt))),
2977 (V6_vcombine_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
2978 Requires<[UseHVXDbl]>;
2979
Krzysztof Parzyszek302a9d42017-07-14 19:02:32 +00002980def SDTHexagonVPACK: SDTypeProfile<1, 2, [SDTCisSameAs<1, 2>, SDTCisVec<1>]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002981
Krzysztof Parzyszek302a9d42017-07-14 19:02:32 +00002982def HexagonVPACKE: SDNode<"HexagonISD::VPACKE", SDTHexagonVPACK>;
2983def HexagonVPACKO: SDNode<"HexagonISD::VPACKO", SDTHexagonVPACK>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002984
Krzysztof Parzyszek302a9d42017-07-14 19:02:32 +00002985let Predicates = [UseHVXSgl] in {
2986 def: Pat<(v64i8 (HexagonVPACKE (v64i8 VectorRegs:$Vs),
2987 (v64i8 VectorRegs:$Vt))),
2988 (V6_vpackeb VectorRegs:$Vs, VectorRegs:$Vt)>;
2989 def: Pat<(v64i8 (HexagonVPACKO (v64i8 VectorRegs:$Vs),
2990 (v64i8 VectorRegs:$Vt))),
2991 (V6_vpackob VectorRegs:$Vs, VectorRegs:$Vt)>;
2992 def: Pat<(v32i16 (HexagonVPACKE (v32i16 VectorRegs:$Vs),
2993 (v32i16 VectorRegs:$Vt))),
2994 (V6_vpackeh VectorRegs:$Vs, VectorRegs:$Vt)>;
2995 def: Pat<(v32i16 (HexagonVPACKO (v32i16 VectorRegs:$Vs),
2996 (v32i16 VectorRegs:$Vt))),
2997 (V6_vpackoh VectorRegs:$Vs, VectorRegs:$Vt)>;
2998}
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00002999
Krzysztof Parzyszek302a9d42017-07-14 19:02:32 +00003000let Predicates = [UseHVXDbl] in {
3001 def: Pat<(v128i8 (HexagonVPACKE (v128i8 VecDblRegs:$Vs),
3002 (v128i8 VecDblRegs:$Vt))),
3003 (V6_vpackeb_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>;
3004 def: Pat<(v128i8 (HexagonVPACKO (v128i8 VecDblRegs:$Vs),
3005 (v128i8 VecDblRegs:$Vt))),
3006 (V6_vpackob_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>;
3007 def: Pat<(v64i16 (HexagonVPACKE (v64i16 VecDblRegs:$Vs),
3008 (v64i16 VecDblRegs:$Vt))),
3009 (V6_vpackeh_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>;
3010 def: Pat<(v64i16 (HexagonVPACKO (v64i16 VecDblRegs:$Vs),
3011 (v64i16 VecDblRegs:$Vt))),
3012 (V6_vpackoh_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>;
3013}
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003014
3015def V2I1: PatLeaf<(v2i1 PredRegs:$R)>;
3016def V4I1: PatLeaf<(v4i1 PredRegs:$R)>;
3017def V8I1: PatLeaf<(v8i1 PredRegs:$R)>;
3018def V4I8: PatLeaf<(v4i8 IntRegs:$R)>;
3019def V2I16: PatLeaf<(v2i16 IntRegs:$R)>;
3020def V8I8: PatLeaf<(v8i8 DoubleRegs:$R)>;
3021def V4I16: PatLeaf<(v4i16 DoubleRegs:$R)>;
3022def V2I32: PatLeaf<(v2i32 DoubleRegs:$R)>;
3023
3024
3025multiclass bitconvert_32<ValueType a, ValueType b> {
3026 def : Pat <(b (bitconvert (a IntRegs:$src))),
3027 (b IntRegs:$src)>;
3028 def : Pat <(a (bitconvert (b IntRegs:$src))),
3029 (a IntRegs:$src)>;
3030}
3031
3032multiclass bitconvert_64<ValueType a, ValueType b> {
3033 def : Pat <(b (bitconvert (a DoubleRegs:$src))),
3034 (b DoubleRegs:$src)>;
3035 def : Pat <(a (bitconvert (b DoubleRegs:$src))),
3036 (a DoubleRegs:$src)>;
3037}
3038
3039// Bit convert vector types to integers.
3040defm : bitconvert_32<v4i8, i32>;
3041defm : bitconvert_32<v2i16, i32>;
3042defm : bitconvert_64<v8i8, i64>;
3043defm : bitconvert_64<v4i16, i64>;
3044defm : bitconvert_64<v2i32, i64>;
3045
3046def: Pat<(sra (v4i16 DoubleRegs:$src1), u4_0ImmPred:$src2),
3047 (S2_asr_i_vh DoubleRegs:$src1, imm:$src2)>;
3048def: Pat<(srl (v4i16 DoubleRegs:$src1), u4_0ImmPred:$src2),
3049 (S2_lsr_i_vh DoubleRegs:$src1, imm:$src2)>;
3050def: Pat<(shl (v4i16 DoubleRegs:$src1), u4_0ImmPred:$src2),
3051 (S2_asl_i_vh DoubleRegs:$src1, imm:$src2)>;
3052
3053def: Pat<(sra (v2i32 DoubleRegs:$src1), u5_0ImmPred:$src2),
3054 (S2_asr_i_vw DoubleRegs:$src1, imm:$src2)>;
3055def: Pat<(srl (v2i32 DoubleRegs:$src1), u5_0ImmPred:$src2),
3056 (S2_lsr_i_vw DoubleRegs:$src1, imm:$src2)>;
3057def: Pat<(shl (v2i32 DoubleRegs:$src1), u5_0ImmPred:$src2),
3058 (S2_asl_i_vw DoubleRegs:$src1, imm:$src2)>;
3059
3060def : Pat<(v2i16 (add (v2i16 IntRegs:$src1), (v2i16 IntRegs:$src2))),
3061 (A2_svaddh IntRegs:$src1, IntRegs:$src2)>;
3062
3063def : Pat<(v2i16 (sub (v2i16 IntRegs:$src1), (v2i16 IntRegs:$src2))),
3064 (A2_svsubh IntRegs:$src1, IntRegs:$src2)>;
3065
Krzysztof Parzyszekf85dd9f2017-07-10 20:16:44 +00003066def SDTHexagonVSPLAT: SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVT<1, i32>]>;
3067def HexagonVSPLAT: SDNode<"HexagonISD::VSPLAT", SDTHexagonVSPLAT>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003068
3069// Replicate the low 8-bits from 32-bits input register into each of the
3070// four bytes of 32-bits destination register.
Krzysztof Parzyszekf85dd9f2017-07-10 20:16:44 +00003071def: Pat<(v4i8 (HexagonVSPLAT I32:$Rs)), (S2_vsplatrb I32:$Rs)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003072
3073// Replicate the low 16-bits from 32-bits input register into each of the
3074// four halfwords of 64-bits destination register.
Krzysztof Parzyszekf85dd9f2017-07-10 20:16:44 +00003075def: Pat<(v4i16 (HexagonVSPLAT I32:$Rs)), (S2_vsplatrh I32:$Rs)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003076
Krzysztof Parzyszek89b2d7c2017-07-13 18:17:58 +00003077def: Pat<(v2i32 (HexagonVSPLAT s8_0ImmPred:$s8)),
3078 (A2_combineii imm:$s8, imm:$s8)>;
3079def: Pat<(v2i32 (HexagonVSPLAT I32:$Rs)), (A2_combinew I32:$Rs, I32:$Rs)>;
3080
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003081
3082class VArith_pat <InstHexagon MI, SDNode Op, PatFrag Type>
3083 : Pat <(Op Type:$Rss, Type:$Rtt),
3084 (MI Type:$Rss, Type:$Rtt)>;
3085
3086def: VArith_pat <A2_vaddub, add, V8I8>;
3087def: VArith_pat <A2_vaddh, add, V4I16>;
3088def: VArith_pat <A2_vaddw, add, V2I32>;
3089def: VArith_pat <A2_vsubub, sub, V8I8>;
3090def: VArith_pat <A2_vsubh, sub, V4I16>;
3091def: VArith_pat <A2_vsubw, sub, V2I32>;
3092
3093def: VArith_pat <A2_and, and, V2I16>;
3094def: VArith_pat <A2_xor, xor, V2I16>;
3095def: VArith_pat <A2_or, or, V2I16>;
3096
3097def: VArith_pat <A2_andp, and, V8I8>;
3098def: VArith_pat <A2_andp, and, V4I16>;
3099def: VArith_pat <A2_andp, and, V2I32>;
3100def: VArith_pat <A2_orp, or, V8I8>;
3101def: VArith_pat <A2_orp, or, V4I16>;
3102def: VArith_pat <A2_orp, or, V2I32>;
3103def: VArith_pat <A2_xorp, xor, V8I8>;
3104def: VArith_pat <A2_xorp, xor, V4I16>;
3105def: VArith_pat <A2_xorp, xor, V2I32>;
3106
Krzysztof Parzyszek89b2d7c2017-07-13 18:17:58 +00003107def: Pat<(v2i32 (sra V2I32:$b, (v2i32 (HexagonVSPLAT u5_0ImmPred:$c)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003108 (S2_asr_i_vw V2I32:$b, imm:$c)>;
Krzysztof Parzyszek89b2d7c2017-07-13 18:17:58 +00003109def: Pat<(v2i32 (srl V2I32:$b, (v2i32 (HexagonVSPLAT u5_0ImmPred:$c)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003110 (S2_lsr_i_vw V2I32:$b, imm:$c)>;
Krzysztof Parzyszek89b2d7c2017-07-13 18:17:58 +00003111def: Pat<(v2i32 (shl V2I32:$b, (v2i32 (HexagonVSPLAT u5_0ImmPred:$c)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003112 (S2_asl_i_vw V2I32:$b, imm:$c)>;
3113
Krzysztof Parzyszekf85dd9f2017-07-10 20:16:44 +00003114def: Pat<(v4i16 (sra V4I16:$b, (v4i16 (HexagonVSPLAT u4_0ImmPred:$c)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003115 (S2_asr_i_vh V4I16:$b, imm:$c)>;
Krzysztof Parzyszekf85dd9f2017-07-10 20:16:44 +00003116def: Pat<(v4i16 (srl V4I16:$b, (v4i16 (HexagonVSPLAT u4_0ImmPred:$c)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003117 (S2_lsr_i_vh V4I16:$b, imm:$c)>;
Krzysztof Parzyszekf85dd9f2017-07-10 20:16:44 +00003118def: Pat<(v4i16 (shl V4I16:$b, (v4i16 (HexagonVSPLAT u4_0ImmPred:$c)))),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003119 (S2_asl_i_vh V4I16:$b, imm:$c)>;
3120
3121
Krzysztof Parzyszekf85dd9f2017-07-10 20:16:44 +00003122def SDTHexagonVShift
3123 : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisVec<0>, SDTCisVT<2, i32>]>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003124
Krzysztof Parzyszekf85dd9f2017-07-10 20:16:44 +00003125def HexagonVASL: SDNode<"HexagonISD::VASL", SDTHexagonVShift>;
3126def HexagonVASR: SDNode<"HexagonISD::VASR", SDTHexagonVShift>;
3127def HexagonVLSR: SDNode<"HexagonISD::VLSR", SDTHexagonVShift>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003128
Krzysztof Parzyszekf85dd9f2017-07-10 20:16:44 +00003129def: Pat<(v2i32 (HexagonVASL V2I32:$Rs, u5_0ImmPred:$u5)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003130 (S2_asl_i_vw V2I32:$Rs, imm:$u5)>;
Krzysztof Parzyszekf85dd9f2017-07-10 20:16:44 +00003131def: Pat<(v4i16 (HexagonVASL V4I16:$Rs, u4_0ImmPred:$u4)),
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003132 (S2_asl_i_vh V4I16:$Rs, imm:$u4)>;
Krzysztof Parzyszekf85dd9f2017-07-10 20:16:44 +00003133def: Pat<(v2i32 (HexagonVASR V2I32:$Rs, u5_0ImmPred:$u5)),
3134 (S2_asr_i_vw V2I32:$Rs, imm:$u5)>;
3135def: Pat<(v4i16 (HexagonVASR V4I16:$Rs, u4_0ImmPred:$u4)),
3136 (S2_asr_i_vh V4I16:$Rs, imm:$u4)>;
3137def: Pat<(v2i32 (HexagonVLSR V2I32:$Rs, u5_0ImmPred:$u5)),
3138 (S2_lsr_i_vw V2I32:$Rs, imm:$u5)>;
3139def: Pat<(v4i16 (HexagonVLSR V4I16:$Rs, u4_0ImmPred:$u4)),
3140 (S2_lsr_i_vh V4I16:$Rs, imm:$u4)>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003141
3142class vshift_rr_pat<InstHexagon MI, SDNode Op, PatFrag Value>
3143 : Pat <(Op Value:$Rs, I32:$Rt),
3144 (MI Value:$Rs, I32:$Rt)>;
3145
Krzysztof Parzyszekf85dd9f2017-07-10 20:16:44 +00003146def: vshift_rr_pat <S2_asl_r_vw, HexagonVASL, V2I32>;
3147def: vshift_rr_pat <S2_asl_r_vh, HexagonVASL, V4I16>;
3148def: vshift_rr_pat <S2_asr_r_vw, HexagonVASR, V2I32>;
3149def: vshift_rr_pat <S2_asr_r_vh, HexagonVASR, V4I16>;
3150def: vshift_rr_pat <S2_lsr_r_vw, HexagonVLSR, V2I32>;
3151def: vshift_rr_pat <S2_lsr_r_vh, HexagonVLSR, V4I16>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003152
3153
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003154class vcmp_vi1_pat<InstHexagon MI, PatFrag Op, PatFrag InVal, ValueType OutTy>
3155 : Pat <(OutTy (Op InVal:$Rs, InVal:$Rt)),
3156 (MI InVal:$Rs, InVal:$Rt)>;
3157
3158def: vcmp_vi1_pat<A2_vcmpweq, seteq, V2I32, v2i1>;
3159def: vcmp_vi1_pat<A2_vcmpwgt, setgt, V2I32, v2i1>;
3160def: vcmp_vi1_pat<A2_vcmpwgtu, setugt, V2I32, v2i1>;
3161
3162def: vcmp_vi1_pat<A2_vcmpheq, seteq, V4I16, v4i1>;
3163def: vcmp_vi1_pat<A2_vcmphgt, setgt, V4I16, v4i1>;
3164def: vcmp_vi1_pat<A2_vcmphgtu, setugt, V4I16, v4i1>;
3165
3166def: Pat<(mul V2I32:$Rs, V2I32:$Rt),
3167 (PS_vmulw DoubleRegs:$Rs, DoubleRegs:$Rt)>;
3168def: Pat<(add V2I32:$Rx, (mul V2I32:$Rs, V2I32:$Rt)),
3169 (PS_vmulw_acc DoubleRegs:$Rx, DoubleRegs:$Rs, DoubleRegs:$Rt)>;
3170
3171
3172// Adds two v4i8: Hexagon does not have an insn for this one, so we
3173// use the double add v8i8, and use only the low part of the result.
3174def: Pat<(v4i8 (add (v4i8 IntRegs:$Rs), (v4i8 IntRegs:$Rt))),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003175 (LoReg (A2_vaddub (ToZext64 $Rs), (ToZext64 $Rt)))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003176
3177// Subtract two v4i8: Hexagon does not have an insn for this one, so we
3178// use the double sub v8i8, and use only the low part of the result.
3179def: Pat<(v4i8 (sub (v4i8 IntRegs:$Rs), (v4i8 IntRegs:$Rt))),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003180 (LoReg (A2_vsubub (ToZext64 $Rs), (ToZext64 $Rt)))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003181
3182//
3183// No 32 bit vector mux.
3184//
3185def: Pat<(v4i8 (select I1:$Pu, V4I8:$Rs, V4I8:$Rt)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003186 (LoReg (C2_vmux I1:$Pu, (ToZext64 $Rs), (ToZext64 $Rt)))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003187def: Pat<(v2i16 (select I1:$Pu, V2I16:$Rs, V2I16:$Rt)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003188 (LoReg (C2_vmux I1:$Pu, (ToZext64 $Rs), (ToZext64 $Rt)))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003189
3190//
3191// 64-bit vector mux.
3192//
3193def: Pat<(v8i8 (vselect V8I1:$Pu, V8I8:$Rs, V8I8:$Rt)),
3194 (C2_vmux V8I1:$Pu, V8I8:$Rs, V8I8:$Rt)>;
3195def: Pat<(v4i16 (vselect V4I1:$Pu, V4I16:$Rs, V4I16:$Rt)),
3196 (C2_vmux V4I1:$Pu, V4I16:$Rs, V4I16:$Rt)>;
3197def: Pat<(v2i32 (vselect V2I1:$Pu, V2I32:$Rs, V2I32:$Rt)),
3198 (C2_vmux V2I1:$Pu, V2I32:$Rs, V2I32:$Rt)>;
3199
3200//
3201// No 32 bit vector compare.
3202//
3203def: Pat<(i1 (seteq V4I8:$Rs, V4I8:$Rt)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003204 (A2_vcmpbeq (ToZext64 $Rs), (ToZext64 $Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003205def: Pat<(i1 (setgt V4I8:$Rs, V4I8:$Rt)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003206 (A4_vcmpbgt (ToZext64 $Rs), (ToZext64 $Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003207def: Pat<(i1 (setugt V4I8:$Rs, V4I8:$Rt)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003208 (A2_vcmpbgtu (ToZext64 $Rs), (ToZext64 $Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003209
3210def: Pat<(i1 (seteq V2I16:$Rs, V2I16:$Rt)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003211 (A2_vcmpheq (ToZext64 $Rs), (ToZext64 $Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003212def: Pat<(i1 (setgt V2I16:$Rs, V2I16:$Rt)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003213 (A2_vcmphgt (ToZext64 $Rs), (ToZext64 $Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003214def: Pat<(i1 (setugt V2I16:$Rs, V2I16:$Rt)),
Krzysztof Parzyszek4b4012a2016-11-05 21:02:54 +00003215 (A2_vcmphgtu (ToZext64 $Rs), (ToZext64 $Rt))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003216
3217
3218class InvertCmp_pat<InstHexagon InvMI, PatFrag CmpOp, PatFrag Value,
3219 ValueType CmpTy>
3220 : Pat<(CmpTy (CmpOp Value:$Rs, Value:$Rt)),
3221 (InvMI Value:$Rt, Value:$Rs)>;
3222
3223// Map from a compare operation to the corresponding instruction with the
3224// order of operands reversed, e.g. x > y --> cmp.lt(y,x).
3225def: InvertCmp_pat<A4_vcmpbgt, setlt, V8I8, i1>;
3226def: InvertCmp_pat<A4_vcmpbgt, setlt, V8I8, v8i1>;
3227def: InvertCmp_pat<A2_vcmphgt, setlt, V4I16, i1>;
3228def: InvertCmp_pat<A2_vcmphgt, setlt, V4I16, v4i1>;
3229def: InvertCmp_pat<A2_vcmpwgt, setlt, V2I32, i1>;
3230def: InvertCmp_pat<A2_vcmpwgt, setlt, V2I32, v2i1>;
3231
3232def: InvertCmp_pat<A2_vcmpbgtu, setult, V8I8, i1>;
3233def: InvertCmp_pat<A2_vcmpbgtu, setult, V8I8, v8i1>;
3234def: InvertCmp_pat<A2_vcmphgtu, setult, V4I16, i1>;
3235def: InvertCmp_pat<A2_vcmphgtu, setult, V4I16, v4i1>;
3236def: InvertCmp_pat<A2_vcmpwgtu, setult, V2I32, i1>;
3237def: InvertCmp_pat<A2_vcmpwgtu, setult, V2I32, v2i1>;
3238
3239// Map from vcmpne(Rss) -> !vcmpew(Rss).
3240// rs != rt -> !(rs == rt).
3241def: Pat<(v2i1 (setne V2I32:$Rs, V2I32:$Rt)),
3242 (C2_not (v2i1 (A2_vcmpbeq V2I32:$Rs, V2I32:$Rt)))>;
3243
3244
3245// Truncate: from vector B copy all 'E'ven 'B'yte elements:
3246// A[0] = B[0]; A[1] = B[2]; A[2] = B[4]; A[3] = B[6];
3247def: Pat<(v4i8 (trunc V4I16:$Rs)),
3248 (S2_vtrunehb V4I16:$Rs)>;
3249
3250// Truncate: from vector B copy all 'O'dd 'B'yte elements:
3251// A[0] = B[1]; A[1] = B[3]; A[2] = B[5]; A[3] = B[7];
3252// S2_vtrunohb
3253
3254// Truncate: from vectors B and C copy all 'E'ven 'H'alf-word elements:
3255// A[0] = B[0]; A[1] = B[2]; A[2] = C[0]; A[3] = C[2];
3256// S2_vtruneh
3257
3258def: Pat<(v2i16 (trunc V2I32:$Rs)),
3259 (LoReg (S2_packhl (HiReg $Rs), (LoReg $Rs)))>;
3260
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003261def: Pat<(v4i16 (zext V4I8:$Rs)), (S2_vzxtbh V4I8:$Rs)>;
3262def: Pat<(v2i32 (zext V2I16:$Rs)), (S2_vzxthw V2I16:$Rs)>;
3263def: Pat<(v4i16 (anyext V4I8:$Rs)), (S2_vzxtbh V4I8:$Rs)>;
3264def: Pat<(v2i32 (anyext V2I16:$Rs)), (S2_vzxthw V2I16:$Rs)>;
3265def: Pat<(v4i16 (sext V4I8:$Rs)), (S2_vsxtbh V4I8:$Rs)>;
3266def: Pat<(v2i32 (sext V2I16:$Rs)), (S2_vsxthw V2I16:$Rs)>;
3267
3268// Sign extends a v2i8 into a v2i32.
3269def: Pat<(v2i32 (sext_inreg V2I32:$Rs, v2i8)),
3270 (A2_combinew (A2_sxtb (HiReg $Rs)), (A2_sxtb (LoReg $Rs)))>;
3271
3272// Sign extends a v2i16 into a v2i32.
3273def: Pat<(v2i32 (sext_inreg V2I32:$Rs, v2i16)),
3274 (A2_combinew (A2_sxth (HiReg $Rs)), (A2_sxth (LoReg $Rs)))>;
3275
3276
3277// Multiplies two v2i16 and returns a v2i32. We are using here the
3278// saturating multiply, as hexagon does not provide a non saturating
3279// vector multiply, and saturation does not impact the result that is
3280// in double precision of the operands.
3281
3282// Multiplies two v2i16 vectors: as Hexagon does not have a multiply
3283// with the C semantics for this one, this pattern uses the half word
3284// multiply vmpyh that takes two v2i16 and returns a v2i32. This is
3285// then truncated to fit this back into a v2i16 and to simulate the
3286// wrap around semantics for unsigned in C.
3287def vmpyh: OutPatFrag<(ops node:$Rs, node:$Rt),
3288 (M2_vmpy2s_s0 (i32 $Rs), (i32 $Rt))>;
3289
3290def: Pat<(v2i16 (mul V2I16:$Rs, V2I16:$Rt)),
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +00003291 (LoReg (S2_vtrunewh (A2_combineii 0, 0),
3292 (vmpyh V2I16:$Rs, V2I16:$Rt)))>;
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003293
3294// Multiplies two v4i16 vectors.
3295def: Pat<(v4i16 (mul V4I16:$Rs, V4I16:$Rt)),
3296 (S2_vtrunewh (vmpyh (HiReg $Rs), (HiReg $Rt)),
3297 (vmpyh (LoReg $Rs), (LoReg $Rt)))>;
3298
3299def VMPYB_no_V5: OutPatFrag<(ops node:$Rs, node:$Rt),
3300 (S2_vtrunewh (vmpyh (HiReg (S2_vsxtbh $Rs)), (HiReg (S2_vsxtbh $Rt))),
3301 (vmpyh (LoReg (S2_vsxtbh $Rs)), (LoReg (S2_vsxtbh $Rt))))>;
3302
3303// Multiplies two v4i8 vectors.
3304def: Pat<(v4i8 (mul V4I8:$Rs, V4I8:$Rt)),
3305 (S2_vtrunehb (M5_vmpybsu V4I8:$Rs, V4I8:$Rt))>,
3306 Requires<[HasV5T]>;
3307
3308def: Pat<(v4i8 (mul V4I8:$Rs, V4I8:$Rt)),
3309 (S2_vtrunehb (VMPYB_no_V5 V4I8:$Rs, V4I8:$Rt))>;
3310
3311// Multiplies two v8i8 vectors.
3312def: Pat<(v8i8 (mul V8I8:$Rs, V8I8:$Rt)),
3313 (A2_combinew (S2_vtrunehb (M5_vmpybsu (HiReg $Rs), (HiReg $Rt))),
3314 (S2_vtrunehb (M5_vmpybsu (LoReg $Rs), (LoReg $Rt))))>,
3315 Requires<[HasV5T]>;
3316
3317def: Pat<(v8i8 (mul V8I8:$Rs, V8I8:$Rt)),
3318 (A2_combinew (S2_vtrunehb (VMPYB_no_V5 (HiReg $Rs), (HiReg $Rt))),
3319 (S2_vtrunehb (VMPYB_no_V5 (LoReg $Rs), (LoReg $Rt))))>;
3320
Krzysztof Parzyszeka8d63dc2016-11-05 15:01:38 +00003321// Truncated store from v4i16 to v4i8.
3322def truncstorev4i8: PatFrag<(ops node:$val, node:$ptr),
3323 (truncstore node:$val, node:$ptr),
3324 [{ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v4i8; }]>;
3325
3326// Truncated store from v2i32 to v2i16.
3327def truncstorev2i16: PatFrag<(ops node:$val, node:$ptr),
3328 (truncstore node:$val, node:$ptr),
3329 [{ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v2i16; }]>;
3330
3331def: Pat<(truncstorev2i16 V2I32:$Rs, I32:$Rt),
3332 (S2_storeri_io I32:$Rt, 0, (LoReg (S2_packhl (HiReg $Rs),
3333 (LoReg $Rs))))>;
3334
3335def: Pat<(truncstorev4i8 V4I16:$Rs, I32:$Rt),
3336 (S2_storeri_io I32:$Rt, 0, (S2_vtrunehb V4I16:$Rs))>;
3337
3338
3339// Zero and sign extended load from v2i8 into v2i16.
3340def zextloadv2i8: PatFrag<(ops node:$ptr), (zextload node:$ptr),
3341 [{ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v2i8; }]>;
3342
3343def sextloadv2i8: PatFrag<(ops node:$ptr), (sextload node:$ptr),
3344 [{ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v2i8; }]>;
3345
3346def: Pat<(v2i16 (zextloadv2i8 I32:$Rs)),
3347 (LoReg (v4i16 (S2_vzxtbh (L2_loadruh_io I32:$Rs, 0))))>;
3348
3349def: Pat<(v2i16 (sextloadv2i8 I32:$Rs)),
3350 (LoReg (v4i16 (S2_vsxtbh (L2_loadrh_io I32:$Rs, 0))))>;
3351
3352def: Pat<(v2i32 (zextloadv2i8 I32:$Rs)),
3353 (S2_vzxthw (LoReg (v4i16 (S2_vzxtbh (L2_loadruh_io I32:$Rs, 0)))))>;
3354
3355def: Pat<(v2i32 (sextloadv2i8 I32:$Rs)),
3356 (S2_vsxthw (LoReg (v4i16 (S2_vsxtbh (L2_loadrh_io I32:$Rs, 0)))))>;
3357
Krzysztof Parzyszekab57c2b2017-02-22 22:28:47 +00003358
3359// Read cycle counter.
3360//
3361def SDTInt64Leaf: SDTypeProfile<1, 0, [SDTCisVT<0, i64>]>;
3362def HexagonREADCYCLE: SDNode<"HexagonISD::READCYCLE", SDTInt64Leaf,
3363 [SDNPHasChain]>;
3364
3365def: Pat<(HexagonREADCYCLE), (A4_tfrcpp UPCYCLE)>;