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