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