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