1*da58b97aSjoerg//=----- AArch64InstrGISel.td - AArch64 GISel target pseudos -*- tablegen -*-=//
2*da58b97aSjoerg//
3*da58b97aSjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*da58b97aSjoerg// See https://llvm.org/LICENSE.txt for license information.
5*da58b97aSjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*da58b97aSjoerg//
7*da58b97aSjoerg//===----------------------------------------------------------------------===//
8*da58b97aSjoerg//
9*da58b97aSjoerg// AArch64 GlobalISel target pseudo instruction definitions. This is kept
10*da58b97aSjoerg// separately from the other tablegen files for organizational purposes, but
11*da58b97aSjoerg// share the same infrastructure.
12*da58b97aSjoerg//
13*da58b97aSjoerg//===----------------------------------------------------------------------===//
14*da58b97aSjoerg
15*da58b97aSjoerg
16*da58b97aSjoergclass AArch64GenericInstruction : GenericInstruction {
17*da58b97aSjoerg  let Namespace = "AArch64";
18*da58b97aSjoerg}
19*da58b97aSjoerg
20*da58b97aSjoerg// A pseudo to represent a relocatable add instruction as part of address
21*da58b97aSjoerg// computation.
22*da58b97aSjoergdef G_ADD_LOW : AArch64GenericInstruction {
23*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
24*da58b97aSjoerg  let InOperandList = (ins type1:$src, type2:$imm);
25*da58b97aSjoerg  let hasSideEffects = 0;
26*da58b97aSjoerg}
27*da58b97aSjoerg
28*da58b97aSjoerg// Pseudo for a rev16 instruction. Produced post-legalization from
29*da58b97aSjoerg// G_SHUFFLE_VECTORs with appropriate masks.
30*da58b97aSjoergdef G_REV16 : AArch64GenericInstruction {
31*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
32*da58b97aSjoerg  let InOperandList = (ins type0:$src);
33*da58b97aSjoerg  let hasSideEffects = 0;
34*da58b97aSjoerg}
35*da58b97aSjoerg
36*da58b97aSjoerg// Pseudo for a rev32 instruction. Produced post-legalization from
37*da58b97aSjoerg// G_SHUFFLE_VECTORs with appropriate masks.
38*da58b97aSjoergdef G_REV32 : AArch64GenericInstruction {
39*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
40*da58b97aSjoerg  let InOperandList = (ins type0:$src);
41*da58b97aSjoerg  let hasSideEffects = 0;
42*da58b97aSjoerg}
43*da58b97aSjoerg
44*da58b97aSjoerg// Pseudo for a rev64 instruction. Produced post-legalization from
45*da58b97aSjoerg// G_SHUFFLE_VECTORs with appropriate masks.
46*da58b97aSjoergdef G_REV64 : AArch64GenericInstruction {
47*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
48*da58b97aSjoerg  let InOperandList = (ins type0:$src);
49*da58b97aSjoerg  let hasSideEffects = 0;
50*da58b97aSjoerg}
51*da58b97aSjoerg
52*da58b97aSjoerg// Represents an uzp1 instruction. Produced post-legalization from
53*da58b97aSjoerg// G_SHUFFLE_VECTORs with appropriate masks.
54*da58b97aSjoergdef G_UZP1 : AArch64GenericInstruction {
55*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
56*da58b97aSjoerg  let InOperandList = (ins type0:$v1, type0:$v2);
57*da58b97aSjoerg  let hasSideEffects = 0;
58*da58b97aSjoerg}
59*da58b97aSjoerg
60*da58b97aSjoerg// Represents an uzp2 instruction. Produced post-legalization from
61*da58b97aSjoerg// G_SHUFFLE_VECTORs with appropriate masks.
62*da58b97aSjoergdef G_UZP2 : AArch64GenericInstruction {
63*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
64*da58b97aSjoerg  let InOperandList = (ins type0:$v1, type0:$v2);
65*da58b97aSjoerg  let hasSideEffects = 0;
66*da58b97aSjoerg}
67*da58b97aSjoerg
68*da58b97aSjoerg// Represents a zip1 instruction. Produced post-legalization from
69*da58b97aSjoerg// G_SHUFFLE_VECTORs with appropriate masks.
70*da58b97aSjoergdef G_ZIP1 : AArch64GenericInstruction {
71*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
72*da58b97aSjoerg  let InOperandList = (ins type0:$v1, type0:$v2);
73*da58b97aSjoerg  let hasSideEffects = 0;
74*da58b97aSjoerg}
75*da58b97aSjoerg
76*da58b97aSjoerg// Represents a zip2 instruction. Produced post-legalization from
77*da58b97aSjoerg// G_SHUFFLE_VECTORs with appropriate masks.
78*da58b97aSjoergdef G_ZIP2 : AArch64GenericInstruction {
79*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
80*da58b97aSjoerg  let InOperandList = (ins type0:$v1, type0:$v2);
81*da58b97aSjoerg  let hasSideEffects = 0;
82*da58b97aSjoerg}
83*da58b97aSjoerg
84*da58b97aSjoerg// Represents a dup instruction. Produced post-legalization from
85*da58b97aSjoerg// G_SHUFFLE_VECTORs with appropriate masks.
86*da58b97aSjoergdef G_DUP: AArch64GenericInstruction {
87*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
88*da58b97aSjoerg  let InOperandList = (ins type1:$lane);
89*da58b97aSjoerg  let hasSideEffects = 0;
90*da58b97aSjoerg}
91*da58b97aSjoerg
92*da58b97aSjoerg// Represents a lane duplicate operation.
93*da58b97aSjoergdef G_DUPLANE8 : AArch64GenericInstruction {
94*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
95*da58b97aSjoerg  let InOperandList = (ins type0:$src, type1:$lane);
96*da58b97aSjoerg  let hasSideEffects = 0;
97*da58b97aSjoerg}
98*da58b97aSjoergdef G_DUPLANE16 : AArch64GenericInstruction {
99*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
100*da58b97aSjoerg  let InOperandList = (ins type0:$src, type1:$lane);
101*da58b97aSjoerg  let hasSideEffects = 0;
102*da58b97aSjoerg}
103*da58b97aSjoergdef G_DUPLANE32 : AArch64GenericInstruction {
104*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
105*da58b97aSjoerg  let InOperandList = (ins type0:$src, type1:$lane);
106*da58b97aSjoerg  let hasSideEffects = 0;
107*da58b97aSjoerg}
108*da58b97aSjoergdef G_DUPLANE64 : AArch64GenericInstruction {
109*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
110*da58b97aSjoerg  let InOperandList = (ins type0:$src, type1:$lane);
111*da58b97aSjoerg  let hasSideEffects = 0;
112*da58b97aSjoerg}
113*da58b97aSjoerg
114*da58b97aSjoerg// Represents a trn1 instruction. Produced post-legalization from
115*da58b97aSjoerg// G_SHUFFLE_VECTORs with appropriate masks.
116*da58b97aSjoergdef G_TRN1 : AArch64GenericInstruction {
117*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
118*da58b97aSjoerg  let InOperandList = (ins type0:$v1, type0:$v2);
119*da58b97aSjoerg  let hasSideEffects = 0;
120*da58b97aSjoerg}
121*da58b97aSjoerg
122*da58b97aSjoerg// Represents a trn2 instruction. Produced post-legalization from
123*da58b97aSjoerg// G_SHUFFLE_VECTORs with appropriate masks.
124*da58b97aSjoergdef G_TRN2 : AArch64GenericInstruction {
125*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
126*da58b97aSjoerg  let InOperandList = (ins type0:$v1, type0:$v2);
127*da58b97aSjoerg  let hasSideEffects = 0;
128*da58b97aSjoerg}
129*da58b97aSjoerg
130*da58b97aSjoerg// Represents an ext instruction. Produced post-legalization from
131*da58b97aSjoerg// G_SHUFFLE_VECTORs with appropriate masks.
132*da58b97aSjoergdef G_EXT: AArch64GenericInstruction {
133*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
134*da58b97aSjoerg  let InOperandList = (ins type0:$v1, type0:$v2, untyped_imm_0:$imm);
135*da58b97aSjoerg  let hasSideEffects = 0;
136*da58b97aSjoerg}
137*da58b97aSjoerg
138*da58b97aSjoerg// Represents a vector G_ASHR with an immediate.
139*da58b97aSjoergdef G_VASHR : AArch64GenericInstruction {
140*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
141*da58b97aSjoerg  let InOperandList = (ins type0:$src1, untyped_imm_0:$imm);
142*da58b97aSjoerg  let hasSideEffects = 0;
143*da58b97aSjoerg}
144*da58b97aSjoerg
145*da58b97aSjoerg// Represents a vector G_LSHR with an immediate.
146*da58b97aSjoergdef G_VLSHR : AArch64GenericInstruction {
147*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
148*da58b97aSjoerg  let InOperandList = (ins type0:$src1, untyped_imm_0:$imm);
149*da58b97aSjoerg  let hasSideEffects = 0;
150*da58b97aSjoerg}
151*da58b97aSjoerg
152*da58b97aSjoerg// Represents an integer to FP conversion on the FPR bank.
153*da58b97aSjoergdef G_SITOF : AArch64GenericInstruction {
154*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
155*da58b97aSjoerg  let InOperandList = (ins type0:$src);
156*da58b97aSjoerg  let hasSideEffects = 0;
157*da58b97aSjoerg}
158*da58b97aSjoergdef G_UITOF : AArch64GenericInstruction {
159*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
160*da58b97aSjoerg  let InOperandList = (ins type0:$src);
161*da58b97aSjoerg  let hasSideEffects = 0;
162*da58b97aSjoerg}
163*da58b97aSjoerg
164*da58b97aSjoergdef G_FCMEQ : AArch64GenericInstruction {
165*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
166*da58b97aSjoerg  let InOperandList = (ins type0:$src1, type1:$src2);
167*da58b97aSjoerg  let hasSideEffects = 0;
168*da58b97aSjoerg}
169*da58b97aSjoerg
170*da58b97aSjoergdef G_FCMGE : AArch64GenericInstruction {
171*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
172*da58b97aSjoerg  let InOperandList = (ins type0:$src1, type1:$src2);
173*da58b97aSjoerg  let hasSideEffects = 0;
174*da58b97aSjoerg}
175*da58b97aSjoerg
176*da58b97aSjoergdef G_FCMGT : AArch64GenericInstruction {
177*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
178*da58b97aSjoerg  let InOperandList = (ins type0:$src1, type1:$src2);
179*da58b97aSjoerg  let hasSideEffects = 0;
180*da58b97aSjoerg}
181*da58b97aSjoerg
182*da58b97aSjoergdef G_FCMEQZ : AArch64GenericInstruction {
183*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
184*da58b97aSjoerg  let InOperandList = (ins type0:$src);
185*da58b97aSjoerg  let hasSideEffects = 0;
186*da58b97aSjoerg}
187*da58b97aSjoerg
188*da58b97aSjoergdef G_FCMGEZ : AArch64GenericInstruction {
189*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
190*da58b97aSjoerg  let InOperandList = (ins type0:$src);
191*da58b97aSjoerg  let hasSideEffects = 0;
192*da58b97aSjoerg}
193*da58b97aSjoerg
194*da58b97aSjoergdef G_FCMGTZ : AArch64GenericInstruction {
195*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
196*da58b97aSjoerg  let InOperandList = (ins type0:$src);
197*da58b97aSjoerg  let hasSideEffects = 0;
198*da58b97aSjoerg}
199*da58b97aSjoerg
200*da58b97aSjoergdef G_FCMLEZ : AArch64GenericInstruction {
201*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
202*da58b97aSjoerg  let InOperandList = (ins type0:$src);
203*da58b97aSjoerg  let hasSideEffects = 0;
204*da58b97aSjoerg}
205*da58b97aSjoerg
206*da58b97aSjoergdef G_FCMLTZ : AArch64GenericInstruction {
207*da58b97aSjoerg  let OutOperandList = (outs type0:$dst);
208*da58b97aSjoerg  let InOperandList = (ins type0:$src);
209*da58b97aSjoerg  let hasSideEffects = 0;
210*da58b97aSjoerg}
211*da58b97aSjoerg
212*da58b97aSjoergdef : GINodeEquiv<G_REV16, AArch64rev16>;
213*da58b97aSjoergdef : GINodeEquiv<G_REV32, AArch64rev32>;
214*da58b97aSjoergdef : GINodeEquiv<G_REV64, AArch64rev64>;
215*da58b97aSjoergdef : GINodeEquiv<G_UZP1, AArch64uzp1>;
216*da58b97aSjoergdef : GINodeEquiv<G_UZP2, AArch64uzp2>;
217*da58b97aSjoergdef : GINodeEquiv<G_ZIP1, AArch64zip1>;
218*da58b97aSjoergdef : GINodeEquiv<G_ZIP2, AArch64zip2>;
219*da58b97aSjoergdef : GINodeEquiv<G_DUP, AArch64dup>;
220*da58b97aSjoergdef : GINodeEquiv<G_DUPLANE8, AArch64duplane8>;
221*da58b97aSjoergdef : GINodeEquiv<G_DUPLANE16, AArch64duplane16>;
222*da58b97aSjoergdef : GINodeEquiv<G_DUPLANE32, AArch64duplane32>;
223*da58b97aSjoergdef : GINodeEquiv<G_DUPLANE64, AArch64duplane64>;
224*da58b97aSjoergdef : GINodeEquiv<G_TRN1, AArch64trn1>;
225*da58b97aSjoergdef : GINodeEquiv<G_TRN2, AArch64trn2>;
226*da58b97aSjoergdef : GINodeEquiv<G_EXT, AArch64ext>;
227*da58b97aSjoergdef : GINodeEquiv<G_VASHR, AArch64vashr>;
228*da58b97aSjoergdef : GINodeEquiv<G_VLSHR, AArch64vlshr>;
229*da58b97aSjoergdef : GINodeEquiv<G_SITOF, AArch64sitof>;
230*da58b97aSjoergdef : GINodeEquiv<G_UITOF, AArch64uitof>;
231*da58b97aSjoerg
232*da58b97aSjoergdef : GINodeEquiv<G_FCMEQ, AArch64fcmeq>;
233*da58b97aSjoergdef : GINodeEquiv<G_FCMGE, AArch64fcmge>;
234*da58b97aSjoergdef : GINodeEquiv<G_FCMGT, AArch64fcmgt>;
235*da58b97aSjoerg
236*da58b97aSjoergdef : GINodeEquiv<G_FCMEQZ, AArch64fcmeqz>;
237*da58b97aSjoergdef : GINodeEquiv<G_FCMGEZ, AArch64fcmgez>;
238*da58b97aSjoergdef : GINodeEquiv<G_FCMGTZ, AArch64fcmgtz>;
239*da58b97aSjoergdef : GINodeEquiv<G_FCMLEZ, AArch64fcmlez>;
240*da58b97aSjoergdef : GINodeEquiv<G_FCMLTZ, AArch64fcmltz>;
241*da58b97aSjoerg
242*da58b97aSjoergdef : GINodeEquiv<G_EXTRACT_VECTOR_ELT, vector_extract>;
243*da58b97aSjoerg
244*da58b97aSjoerg// These are patterns that we only use for GlobalISel via the importer.
245*da58b97aSjoergdef : Pat<(f32 (fadd (vector_extract (v2f32 FPR64:$Rn), (i64 0)),
246*da58b97aSjoerg                     (vector_extract (v2f32 FPR64:$Rn), (i64 1)))),
247*da58b97aSjoerg           (f32 (FADDPv2i32p (v2f32 FPR64:$Rn)))>;
248*da58b97aSjoerg
249*da58b97aSjoerglet Predicates = [HasNEON] in {
250*da58b97aSjoerg  def : Pat<(v2f64 (sint_to_fp v2i32:$src)),
251*da58b97aSjoerg            (SCVTFv2f64 (SSHLLv2i32_shift V64:$src, 0))>;
252*da58b97aSjoerg  def : Pat<(v2f64 (uint_to_fp v2i32:$src)),
253*da58b97aSjoerg            (UCVTFv2f64 (USHLLv2i32_shift V64:$src, 0))>;
254*da58b97aSjoerg  def : Pat<(v2f32 (sint_to_fp v2i64:$src)),
255*da58b97aSjoerg            (FCVTNv2i32 (SCVTFv2f64 V128:$src))>;
256*da58b97aSjoerg  def : Pat<(v2f32 (uint_to_fp v2i64:$src)),
257*da58b97aSjoerg            (FCVTNv2i32 (UCVTFv2f64 V128:$src))>;
258*da58b97aSjoerg
259*da58b97aSjoerg  def : Pat<(v2i64 (fp_to_sint v2f32:$src)),
260*da58b97aSjoerg            (FCVTZSv2f64 (FCVTLv2i32 V64:$src))>;
261*da58b97aSjoerg  def : Pat<(v2i64 (fp_to_uint v2f32:$src)),
262*da58b97aSjoerg            (FCVTZUv2f64 (FCVTLv2i32 V64:$src))>;
263*da58b97aSjoerg  def : Pat<(v2i32 (fp_to_sint v2f64:$src)),
264*da58b97aSjoerg            (XTNv2i32 (FCVTZSv2f64 V128:$src))>;
265*da58b97aSjoerg  def : Pat<(v2i32 (fp_to_uint v2f64:$src)),
266*da58b97aSjoerg            (XTNv2i32 (FCVTZUv2f64 V128:$src))>;
267*da58b97aSjoerg
268*da58b97aSjoerg}
269*da58b97aSjoerg
270*da58b97aSjoerglet Predicates = [HasNoLSE] in {
271*da58b97aSjoergdef : Pat<(atomic_cmp_swap_8 GPR64:$addr, GPR32:$desired, GPR32:$new),
272*da58b97aSjoerg          (CMP_SWAP_8 GPR64:$addr, GPR32:$desired, GPR32:$new)>;
273*da58b97aSjoerg
274*da58b97aSjoergdef : Pat<(atomic_cmp_swap_16 GPR64:$addr, GPR32:$desired, GPR32:$new),
275*da58b97aSjoerg          (CMP_SWAP_16 GPR64:$addr, GPR32:$desired, GPR32:$new)>;
276*da58b97aSjoerg
277*da58b97aSjoergdef : Pat<(atomic_cmp_swap_32 GPR64:$addr, GPR32:$desired, GPR32:$new),
278*da58b97aSjoerg          (CMP_SWAP_32 GPR64:$addr, GPR32:$desired, GPR32:$new)>;
279*da58b97aSjoerg
280*da58b97aSjoergdef : Pat<(atomic_cmp_swap_64 GPR64:$addr, GPR64:$desired, GPR64:$new),
281*da58b97aSjoerg          (CMP_SWAP_64 GPR64:$addr, GPR64:$desired, GPR64:$new)>;
282*da58b97aSjoerg}
283*da58b97aSjoerg
284*da58b97aSjoergdef : Pat<(int_aarch64_stlxp GPR64:$lo, GPR64:$hi, GPR64:$addr),
285*da58b97aSjoerg          (STLXPX GPR64:$lo, GPR64:$hi, GPR64:$addr)>;
286*da58b97aSjoergdef : Pat<(int_aarch64_stxp GPR64:$lo, GPR64:$hi, GPR64:$addr),
287*da58b97aSjoerg          (STXPX GPR64:$lo, GPR64:$hi, GPR64:$addr)>;
288